Class SimpleMappingLookup
- All Implemented Interfaces:
MappingLookup,MappingSink
MappingLookup which can be mutated via the implemented MappingSink
interface.
Thread safety and concurrency
Instances of this class can be shared across multiple threads for as long as no instance is mutated via the
methods provided by MappingSink. More specifically, the thread safety and concurrency semantics of this class
are identical to the semantics of HashMap. It is as such not recommended to make use of this class
in asynchronous or concurrent environments.
Instances of this class can be freely shared by multiple Remapper instances within the bounds of
aforementioned restrictions.
Method overloading, inheritance and other remapping restrictions
Instances of this class do not handle method overloading and inheritance overall - that is every method
and field is considered to be independent and is considered to exist as-is. Thus,
MappingSink.remapMember(MemberRef, String) must be called for each child class that might override
the method. Furthermore, remapMember(MemberRef, String) should also be called even if an override
does not explicitly occur as it is still possible for java-bytecode to refer the members that might not exist
as-is but exist in the parent class.
This implementation prohibits renaming the initialisation methods <init> and <clinit> or renaming methods to this name - fields may be renamed from and to this name regardless in case it is required for more advanced obfuscation.
When making use of this lookup implementation, layered mappings should either be implemented by squashing/chaining
multiple MappingLookup instances together in an uber-lookup instance or by calling
Remapper.remapNode(org.objectweb.asm.tree.ClassNode, StringBuilder) at least once per mapping layer.
It is generally recommended to go with the former approach as that is the most performance-friendly option, but the latter
approach can also work.
This implementation does not verify the integrity of the remapping requests, so illegal names might be emitted by this lookup instance. Similarly, this implementation does to scan for mapping collisions. Attempting to map a class or class member to two different names will cause the latter remapping request to override the former, omitting no warning nor other indicator while doing so.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription@NotNull StringgetRemappedClassName(@NotNull String srcName) Obtains the name of the class in the destination namespace (or in laymen's terms the remapped name).@Nullable StringgetRemappedClassNameFast(@NotNull String srcName) Obtains the name of the class in the destination namespace (or in laymen's terms the remapped name).@NotNull StringgetRemappedFieldName(@NotNull String srcOwner, @NotNull String srcName, @NotNull String srcDesc) Obtains the name of a field in the destination namespace (or the mapped name).@NotNull StringgetRemappedMethodName(@NotNull String srcOwner, @NotNull String srcName, @NotNull String srcDesc) Obtains the name of a field in the destination namespace (or the mapped name).@Nullable StringgetRemappedParameterName(@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 SimpleMappingLookupremapClass(@NotNull String srcName, @NotNull String dstName) Remaps a specific class.@NotNull SimpleMappingLookupremapMember(@NotNull MemberRef srcRef, @NotNull String dstName) Remaps a class member - that is either a field or a method.@NotNull MappingSinkremapParameter(@NotNull String srcOwner, @NotNull String srcMethodName, @NotNull String srcDesc, int paramIndex, @NotNull String destParamName) Remaps a method parameter.
-
Constructor Details
-
SimpleMappingLookup
public SimpleMappingLookup()
-
-
Method Details
-
getRemappedClassName
Description copied from interface:MappingLookupObtains 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)andMappingLookup.getRemappedClassName(String)be the same implementation for as long asMappingLookup.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:
getRemappedClassNamein interfaceMappingLookup- 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
Description copied from interface:MappingLookupObtains 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)andMappingLookup.getRemappedClassName(String)be the same implementation for as long asMappingLookup.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:
getRemappedClassNameFastin interfaceMappingLookup- 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:MappingLookupObtains 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:
getRemappedFieldNamein interfaceMappingLookup- Parameters:
srcOwner- The name of the owner of the member in the source namespacesrcName- The name of the member in the source namespacesrcDesc- 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:MappingLookupObtains 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:
getRemappedMethodNamein interfaceMappingLookup- Parameters:
srcOwner- The name of the owner of the member in the source namespacesrcName- The name of the member in the source namespacesrcDesc- 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:MappingLookupObtains 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, thennullis returned. This is the default behaviour of this method.The
paramIndexargument is 0-indexed. It does not distinguish between computational categories. Or in other words, for both(IZ)Vand(JZ)Vthe boolean parameter corresponds to aparamIndexvalue of 1, while the integer and long have a value of 0.Callers may throw an
IndexOutOfBoundsExceptionifparamIndexis below 0 or above the amount of parameters as discernible bysrcDesc. 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 whetherparamIndexis 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
MappingLookupinstance does not support remapping parameters, thennullshould be returned unconditionally, without throwing outside of aforementioned reasons.- Specified by:
getRemappedParameterNamein interfaceMappingLookup- 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 impliedthisparameter.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
nullif not applicable.
-
remapClass
@Contract(mutates="this", pure=false, value="_, _ -> this") @NotNull public @NotNull SimpleMappingLookup remapClass(@NotNull @NotNull String srcName, @NotNull @NotNull String dstName) Description copied from interface:MappingSinkRemaps 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 theRemapperimplementation and if implemented would be independent of this method.Class names are defined via the
internal nameof 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:
remapClassin interfaceMappingSink- 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
MappingSinkinstance (i.e. this), for chaining
-
remapMember
@Contract(mutates="this", pure=false, value="_, _ -> this") @NotNull public @NotNull SimpleMappingLookup remapMember(@NotNull @NotNull MemberRef srcRef, @NotNull @NotNull String dstName) Description copied from interface:MappingSinkRemaps 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 thedescriptorof theMemberRef. 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:
remapMemberin interfaceMappingSink- 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
MappingSinkinstance, 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:MappingSinkRemaps a method parameter.The
paramIndexargument is 0-indexed. It does not distinguish between computational categories. Or in other words, for both(IZ)Vand(JZ)Vthe boolean parameter corresponds to aparamIndexvalue of 1, while the integer and long have a value of 0.Callers may throw an
IndexOutOfBoundsExceptionifparamIndexis below 0 or above the amount of parameters as discernible bysrcDesc. 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 whetherparamIndexis a valid value. This is done for performance reasons.If this
MappingSinkinstance does not support remapping method parameters then anUnsupportedOperationExceptionshould be thrown. In cases where libraries are used that link against an older version of stianloader-remapper (namely 0.1.X and earlier), anAbstractMethodErrormay be thrown when attempting to call this method.- Specified by:
remapParameterin interfaceMappingSink- 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 impliedthisargument on non-static methods.destParamName- The name of the parameter in the destination namespace.- Returns:
- The current
MappingSinkinstance, for chaining.
-