Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.embeddedt.modernfix.forge.capability.analysis.CapabilityAnalysisResult;
import org.embeddedt.modernfix.forge.capability.analysis.CapabilityAnalyzer;
import org.embeddedt.modernfix.forge.capability.analysis.CapabilityRef;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.*;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
Expand Down Expand Up @@ -190,6 +191,8 @@ private static LinkedHashMap<CapabilityRef, Integer> collectCapabilityRefs(List<
* Resolves the actual {@link Capability} instances for all refs at class-generation time.
* Uses reflection (with {@code setAccessible}) so private fields are handled without any
* reflection bytecode appearing in the generated class.
* <p>
* Field lookup is delegated to {@link #getRefField(Class, CapabilityRef)}
*/
private static List<Capability<?>> resolveCapabilityValues(LinkedHashMap<CapabilityRef, Integer> capRefIndices) {
@SuppressWarnings("unchecked")
Expand All @@ -199,8 +202,7 @@ private static List<Capability<?>> resolveCapabilityValues(LinkedHashMap<Capabil
try {
Class<?> clazz = Class.forName(ref.owner().replace('/', '.'), false,
CapabilityProviderDispatcherGenerator.class.getClassLoader());
Field field = clazz.getDeclaredField(ref.fieldName());
field.setAccessible(true);
Field field = getRefField(clazz, ref);
caps[entry.getValue()] = (Capability<?>) field.get(null);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to resolve capability field " + ref, e);
Expand All @@ -209,6 +211,27 @@ private static List<Capability<?>> resolveCapabilityValues(LinkedHashMap<Capabil
return Arrays.asList(caps);
}

/**
* Resolves the {@link Field} for the given {@link CapabilityRef},
* falls back to the implemented interfaces if no match is found.
*/
private static @NotNull Field getRefField(Class<?> clazz, CapabilityRef ref) throws NoSuchFieldException {
Field field = null;
try {
field = clazz.getDeclaredField(ref.fieldName());
} catch (NoSuchFieldException ignored) {
for (Class<?> iface : clazz.getInterfaces()) {
try {
field = iface.getDeclaredField(ref.fieldName());
break;
} catch (NoSuchFieldException ignored1) {}
}
}
if (field == null) throw new NoSuchFieldException(ref.fieldName());
field.setAccessible(true);
return field;
}

/**
* Build the dispatch list describing how each provider should be handled.
*/
Expand Down
Loading