Skip to content

Commit

Permalink
changes from review
Browse files Browse the repository at this point in the history
  • Loading branch information
TwilightFlower committed Jun 21, 2024
1 parent 872af3f commit 73749af
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -29,7 +32,8 @@ public final class ClassHeaderMetadata implements FastClassAccessor {
public final int @NotNull [] interfaceIndices;
public final @NotNull String binaryThisName;
public final @Nullable String binarySuperName;
public final String @NotNull [] binaryInterfaceNames;
/** List is unmodifiable */
public final @NotNull List<@NotNull String> binaryInterfaceNames;

/**
* Attempts to parse a class header.
Expand Down Expand Up @@ -68,7 +72,7 @@ public ClassHeaderMetadata(byte @NotNull [] bytes) {
this.superClassIndex = u16(bytes, cpOff + Offsets.pastCpSuperClassU16);
this.interfacesCount = u16(bytes, cpOff + Offsets.pastCpInterfacesCountU16);
this.interfaceIndices = new int[this.interfacesCount];
this.binaryInterfaceNames = new String[this.interfacesCount];
List<String> interfaceNames = new ArrayList<>(this.interfacesCount);

// Parse this&super names
if (constantPoolEntryTypes[thisClassIndex - 1] != ConstantPoolEntryTypes.Class) {
Expand Down Expand Up @@ -108,8 +112,9 @@ public ClassHeaderMetadata(byte @NotNull [] bytes) {
modifiedUtf8(bytes, constantPoolEntryOffsets[interfaceNameIndex - 1] + 1);

this.interfaceIndices[i] = interfaceIndex;
this.binaryInterfaceNames[i] = binaryInterfaceName;
interfaceNames.add(binaryInterfaceName);
}
this.binaryInterfaceNames = Collections.unmodifiableList(interfaceNames);
}

/** Helpers to read big-endian values from class files. */
Expand Down Expand Up @@ -363,7 +368,7 @@ public boolean isModule() {
}

@Override
public String @NotNull [] binaryInterfaceNames() {
public @NotNull List<@NotNull String> binaryInterfaceNames() {
return binaryInterfaceNames;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.gtnewhorizons.retrofuturabootstrap.api;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.Opcodes;
Expand Down Expand Up @@ -31,7 +34,9 @@ public interface FastClassAccessor {
@Nullable
String binarySuperName();

String @NotNull [] binaryInterfaceNames();
/** Binary (slash-separated packages) names of the implemented interfaces, list is unmodifiable */
@NotNull
List<@NotNull String> binaryInterfaceNames();

static OfLoaded ofLoaded(Class<?> loadedClass) {
return new OfLoaded(loadedClass);
Expand Down Expand Up @@ -99,13 +104,16 @@ public boolean isModule() {
}

@Override
public String @NotNull [] binaryInterfaceNames() {
return handle.interfaces == null ? new String[0] : handle.interfaces.toArray(new String[0]);
public @NotNull List<@NotNull String> binaryInterfaceNames() {
return handle.interfaces == null
? Collections.emptyList()
: Collections.unmodifiableList(handle.interfaces);
}
}

final class OfLoaded implements FastClassAccessor {
public final Class<?> handle;
private @Nullable List<@NotNull String> interfacesCache = null;

private OfLoaded(Class<?> handle) {
this.handle = handle;
Expand Down Expand Up @@ -163,13 +171,18 @@ public boolean isModule() {
}

@Override
public String @NotNull [] binaryInterfaceNames() {
public @NotNull List<@NotNull String> binaryInterfaceNames() {
if (interfacesCache != null) {
return interfacesCache;
}

Class<?>[] interfaces = handle.getInterfaces();
String[] binaryInterfaceNames = new String[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
binaryInterfaceNames[i] = interfaces[i].getName().replace('.', '/');
List<String> binaryInterfaceNames = new ArrayList<>(interfaces.length);
for (Class<?> iface : interfaces) {
binaryInterfaceNames.add(iface.getName().replace('.', '/'));
}
return binaryInterfaceNames;
interfacesCache = Collections.unmodifiableList(binaryInterfaceNames);
return interfacesCache;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,45 +84,48 @@ protected String getCommonSuperClass(String type1, String type2) {

private @Nullable InheritanceNode getInheritanceInfo(ExtensibleClassLoader loader, String type) {
InheritanceNode node = inheritanceCache.get(type);
if (node == null) {
FastClassAccessor typeAccessor = loader.findClassMetadata(type.replace('/', '.'));
if (typeAccessor == null) {
Main.logger.warn("Could not find type {} during inheritance search", type);
return null;
}
if (node != null) {
return node;
}

Set<InheritanceNode> allSuperClasses = new HashSet<>();
String superType = typeAccessor.binarySuperName();
InheritanceNode superClass;
// account for Object
if (superType != null) {
superClass = getInheritanceInfo(loader, superType);
if (superClass != null) {
allSuperClasses.addAll(superClass.allSuperClasses);
}
} else {
superClass = null;
}
FastClassAccessor typeAccessor = loader.findClassMetadata(type.replace('/', '.'));
if (typeAccessor == null) {
Main.logger.warn("Could not find type {} during inheritance search", type);
inheritanceCache.put(type, null);
return null;
}

List<InheritanceNode> interfaces = new ArrayList<>();
for (String interfaceType : typeAccessor.binaryInterfaceNames()) {
InheritanceNode iface = getInheritanceInfo(loader, interfaceType);
if (iface != null) {
interfaces.add(iface);
allSuperClasses.addAll(iface.allSuperClasses);
}
Set<InheritanceNode> allSuperClasses = new HashSet<>();
String superType = typeAccessor.binarySuperName();
InheritanceNode superClass;
// account for Object
if (superType != null) {
superClass = getInheritanceInfo(loader, superType);
if (superClass != null) {
allSuperClasses.addAll(superClass.allSuperClasses);
}
} else {
superClass = null;
}

node = new InheritanceNode(typeAccessor, superClass, interfaces, allSuperClasses);
inheritanceCache.put(type, node);
List<InheritanceNode> interfaces = new ArrayList<>();
for (String interfaceType : typeAccessor.binaryInterfaceNames()) {
InheritanceNode iface = getInheritanceInfo(loader, interfaceType);
if (iface != null) {
interfaces.add(iface);
allSuperClasses.addAll(iface.allSuperClasses);
}
}

node = new InheritanceNode(typeAccessor, superClass, interfaces, allSuperClasses);
inheritanceCache.put(type, node);
return node;
}

/**
* Some inheritance metadata. Can be compared with == as long as they're from the same ClassWriter because of caching.
*/
private static class InheritanceNode {
private static final class InheritanceNode {
final @Nullable InheritanceNode superClass;
final @NotNull List<InheritanceNode> interfaces;
final @NotNull FastClassAccessor accessor;
Expand Down

0 comments on commit 73749af

Please sign in to comment.