Package org.stianloader.remapper

# Class SimpleTopLevelLookup

java.lang.Object
org.stianloader.remapper.SimpleTopLevelLookup

All Implemented Interfaces:
  `HierarchyAwareMappingDelegator.TopLevelMemberLookup`

public class SimpleTopLevelLookup extends Object implements HierarchyAwareMappingDelegator.TopLevelMemberLookup
An implementation of `HierarchyAwareMappingDelegator.TopLevelMemberLookup` that works based on a statically computed map of `MemberRef` to `SimpleTopLevelLookup.MemberRealm`. The `SimpleTopLevelLookup.MemberRealm` can be used to obtain the realm members, that is the uses of a realm or the types where the member can be used in (note that in cases where two interfaces define the same method, the set of realm members may overlap - at this point in time there is no good approach of handling that edge-case besides praying it does not occur). A `SimpleTopLevelLookup.MemberRealm` also documents the root definition of a member (in case of the interface edge case, this is by default the most frequently implemented interface - if both interfaces are implemented the same amount of times, it falls back to lexicographic ordering)

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`static class`
`SimpleTopLevelLookup.MemberRealm`
A member realm is a group of class members (so either fields or methods) with the same name (but not necessarily the same descriptor or signature as it is permissible for subclasses to be more/less strict on what they return or consume) but different classes.

## Constructor Summary

Constructors
Constructor
Description
`SimpleTopLevelLookup(@Unmodifiable @NotNull Iterable<@NotNull org.objectweb.asm.tree.ClassNode> applicationClasses)`
Create a `SimpleTopLevelLookup` based on a list of `ClassNodes` that are used to compute the member realms.
`SimpleTopLevelLookup(@Unmodifiable @NotNull List<@NotNull org.objectweb.asm.tree.ClassNode> applicationClasses)`
Deprecated.
Use `SimpleTopLevelLookup(Iterable)` instead.
`SimpleTopLevelLookup(@Unmodifiable @NotNull Map<MemberRef,SimpleTopLevelLookup.MemberRealm> realms)`
Create a `SimpleTopLevelLookup` from an immutable map of `member references` to their respective `SimpleTopLevelLookup.MemberRealm`.

## Method Summary

Modifier and Type
Method
Description
`@NotNull MemberRef`
`getDefinition(@NotNull MemberRef reference)`
Obtain the root-level definition of a member.
`@Nullable SimpleTopLevelLookup.MemberRealm`
`realmOf(@NotNull MemberRef reference)`
Lookup the `SimpleTopLevelLookup.MemberRealm` of a `MemberRef`.
`static @NotNull @Unmodifiable Map<@NotNull MemberRef,@NotNull SimpleTopLevelLookup.MemberRealm>`
`realmsOf(@Unmodifiable @NotNull Iterable<@NotNull org.objectweb.asm.tree.ClassNode> nodes)`
Compute a map of class member to member realm relations from a list of ClassNodes.
`static @NotNull @Unmodifiable Map<@NotNull MemberRef,@NotNull SimpleTopLevelLookup.MemberRealm>`
`realmsOf(@Unmodifiable @NotNull List<@NotNull org.objectweb.asm.tree.ClassNode> nodes)`
Deprecated.
Use `realmsOf(Iterable)` instead.

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

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

## Constructor Details

### SimpleTopLevelLookup

@AvailableSince("0.3.0") public SimpleTopLevelLookup(@NotNull @Unmodifiable @NotNull Iterable<@NotNull org.objectweb.asm.tree.ClassNode> applicationClasses)
Create a `SimpleTopLevelLookup` based on a list of `ClassNodes` that are used to compute the member realms.

JDK Classes or library classes that are irrelevant to the remapping process should be left out for performance (especially memory-related) reasons.

Parameters:
  `applicationClasses` - The classes to analyze
Since:
  0.3.0

### SimpleTopLevelLookup

@Deprecated @ScheduledForRemoval public SimpleTopLevelLookup(@NotNull @Unmodifiable @NotNull List<@NotNull org.objectweb.asm.tree.ClassNode> applicationClasses)
Deprecated.
Use `SimpleTopLevelLookup(Iterable)` instead. This constructor only exists for binary backwards compatibility.
Create a `SimpleTopLevelLookup` based on a list of `ClassNodes` that are used to compute the member realms.

JDK Classes or library classes that are irrelevant to the remapping process should be left out for performance (especially memory-related) reasons.

Parameters:
  `applicationClasses` - The list of classes to analyze

### SimpleTopLevelLookup

public SimpleTopLevelLookup(@NotNull @Unmodifiable @NotNull Map<MemberRef,SimpleTopLevelLookup.MemberRealm> realms)
Create a `SimpleTopLevelLookup` from an immutable map of `member references` to their respective `SimpleTopLevelLookup.MemberRealm`.

JDK Classes or library classes that are irrelevant to the remapping process should be left out for performance (especially memory-related) reasons.

Parameters:
  `realms` - The map to use to lookup the realm of members.

## Method Details

### realmsOf

@NotNull @AvailableSince("0.3.0") public static @NotNull @Unmodifiable Map<@NotNull MemberRef,@NotNull SimpleTopLevelLookup.MemberRealm> realmsOf(@NotNull @Unmodifiable @NotNull Iterable<@NotNull org.objectweb.asm.tree.ClassNode> nodes)
Compute a map of class member to member realm relations from a list of ClassNodes.

The classnodes within the list should include everything that is relevant to the remapping process - so the obfuscated application as well optionally the application that needs to be remapped (e.g. when remapping mods).

However, one currently known edge-case (technically a bug) is that when two interfaces define a method with the same name and descriptor, then if the method hierarchies were to intersect, then the method realms would still be treated separately, even though in reality they are the same realm.

Parameters:
  `nodes` - The `ClassNodes` to process. Members will only be in that collection.
Returns:
  A `Map` that maps `member references` to their respective `SimpleTopLevelLookup.MemberRealm`.
Since:
  0.3.0

### realmsOf

@NotNull @Deprecated @ScheduledForRemoval public static @NotNull @Unmodifiable Map<@NotNull MemberRef,@NotNull SimpleTopLevelLookup.MemberRealm> realmsOf(@NotNull @Unmodifiable @NotNull List<@NotNull org.objectweb.asm.tree.ClassNode> nodes)
Deprecated.
Use `realmsOf(Iterable)` instead. This method is only present for backwards compatibility.
Compute a map of class member to member realm relations from a list of ClassNodes.

The classnodes within the list should include everything that is relevant to the remapping process - so the obfuscated application as well optionally the application that needs to be remapped (e.g. when remapping mods).

However, one currently known edge-case (technically a bug) is that when two interfaces define a method with the same name and descriptor, then if the method hierarchies were to intersect, then the method realms would still be treated separately, even though in reality they are the same realm.

Parameters:
  `nodes` - The list of `ClassNodes` to process. Members will only be in that list.
Returns:
  A `Map` that maps `member references` to their respective `SimpleTopLevelLookup.MemberRealm`.

### getDefinition

@NotNull @Contract(pure=true, value="!null -> !null; null -> fail") @NonBlocking public @NotNull MemberRef getDefinition(@NotNull @NotNull MemberRef reference)
Description copied from interface: `HierarchyAwareMappingDelegator.TopLevelMemberLookup`
Obtain the root-level definition of a member.

Beware that this method may be called for fields and static methods, too. It is imperative that the declaration of fields is also followed as it is possible for javac to emit GETFIELD and PUTFIELD requests where the owner does not match the class where the field in question is defined - this for example might be produced by anonymous enum members.

Implementors are free to handle bridge methods as they please - the only requirement is that they do it persistently and that implementors should be aware that this would cause the bridge methods to potentially have the same name as the method it bridges to. This interface does not mandate any behaviour towards bridge methods and they may be ignored completely (this most likely won't have any notable repercussions anyways unless the codebase in question uses a lot of generics - however, generics are likely to be absent anyways in which case searching for bridge methods may be a bit superfluous).

Changing the computational type of the descriptor of the member is not permitted and will result in an exception being thrown in `HierarchyAwareMappingDelegator.remapMember(MemberRef, String)`. However, outside of that changing the descriptor of a method is permitted, as might for example be needed for bridge methods.

Implementations should return the original source reference for classes or methods they do not know. Under rare cases it is possible for methods to change their descriptor in the JRE, so this fact shouldn't be ignored even if the implementation should handle JRE classes (this specification recommends against handling inheritance beyond the application that needs to be remapped).

Returning a `MemberRef` in a non-source namespace is permissible, but it is highly recommended against doing so. That being said, the input `MemberRef` MUST be in the source namespace.

#### Performance

Stianloader-remapper expects calls to this method to be non-blocking and quick to process. Thus implementors should use caching if appropriate as it is reasonable to expect that this method will be called multiple times (sometimes even consecutively) with the same input argument - even if the returned value should be the same across all calls.

Specified by:
  `getDefinition` in interface `HierarchyAwareMappingDelegator.TopLevelMemberLookup`
Parameters:
  `reference` - The reference of the member in the source namespace.
Returns:
  The reference of the declaration of the member

### realmOf

@Nullable @Contract(pure=true) public @Nullable SimpleTopLevelLookup.MemberRealm realmOf(@NotNull @NotNull MemberRef reference)
Lookup the `SimpleTopLevelLookup.MemberRealm` of a `MemberRef`.

Parameters:
  `reference` - The reference to look up
Returns:
  The corresponding `MemberRef`, or null if not found.