Navigating to method calls within lambdas doesn't work correctly
When double-clicking a method call that's within a lambda in the show calls docker, it will open up the associated class, but won't move the caret or highlight the actual method call itself.
Since lambda methods are synthetic and never referenced directly, the decompiler never visits them, and tokens are never created for them during indexing. When it then tries to look up the token so it knows where to navigate, it doesn't find any and thus doesn't navigate anywhere within the class.
This also affects method calls within <clinit> methods.
Consider this code snippet taken from SpawnPlacements:
private static <T extends Mob> void register(EntityType<T> entityType, SpawnPlacementType spawnPlacementType, Types heightmapType, SpawnPlacements.SpawnPredicate<T> predicate) {
SpawnPlacements.Data $$4 = DATA_BY_TYPE.put(entityType, new SpawnPlacements.Data(heightmapType, spawnPlacementType, predicate));
if ($$4 != null) {
throw new IllegalStateException("Duplicate registration for type " + BuiltInRegistries.ENTITY_TYPE.getKey(entityType));
}
}
public static <T extends Entity> boolean checkSpawnRules(EntityType<T> entityType, ServerLevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) {
SpawnPlacements.Data $$5 = DATA_BY_TYPE.get(entityType);
return $$5 == null || $$5.predicate.test(entityType, level, spawnReason, pos, random);
}
static {
register(EntityType.AXOLOTL, SpawnPlacementTypes.IN_WATER, Types.MOTION_BLOCKING_NO_LEAVES, Axolotl::checkAxolotlSpawnRules);
}
When the class is parsed to map tokens to references, the code sees the call to $$5.predicate.test, which is a bridge method to Axolotl.checkAxolotlSpawnRules. It then creates a reference to Axolotl.checkAxolotlSpawnRules with context SpawnPlacements.checkSpawnRules since that's what ultimately calls it. But when Enigma goes to look up the tokens, it's looking for a reference with context SpawnPlacements.<clinit> because that's where the method is actually referenced.
with a simple test case I made in engima, even a direct call like the call to register in <clinit> couldn't be navigated to
From EnigmaTextTokenCollector:
@Override
public void visitMethod(TextRange range, boolean declaration, String className, String name, MethodDescriptor descriptor) {
super.visitMethod(range, declaration, className, name, descriptor);
Token token = this.getToken(range);
MethodEntry entry = getMethodEntry(className, name, descriptor);
if (declaration) {
this.addDeclaration(token, entry);
this.currentMethod = entry;
} else {
this.addReference(token, entry, this.currentMethod);
}
}
Lambdas and EntryReference is incorrect.