Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation Work #7

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
21 changes: 21 additions & 0 deletions src/main/java/org/parchmentmc/lodestone/LodestoneExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,44 @@
import java.io.InputStreamReader;
import java.net.URL;

/**
* LodestoneExtension is a class that represents the extension configuration for the Lodestone plugin.
* It provides properties and methods to configure and retrieve Minecraft versions.
*/
public class LodestoneExtension {
private final Project project;
private final Property<String> mcVersion;

/**
* Constructs a new LodestoneExtension with the specified project and object factory.
*
* @param project The Gradle project associated with the extension.
* @param factory The object factory used to create properties.
*/
@Inject
public LodestoneExtension(Project project, ObjectFactory factory) {
this.project = project;

this.mcVersion = factory.property(String.class).convention("latest");
}

/**
* Returns the property representing the Minecraft version.
*
* @return The property containing the Minecraft version.
*/
public Property<String> getMcVersion() {
return mcVersion;
}

private String resolvedMcVersion;

/**
* Returns a provider for the resolved Minecraft version.
* The provider lazily resolves and provides the Minecraft version based on the configured Minecraft version property.
*
* @return The provider for the resolved Minecraft version.
*/
public Provider<String> getResolvedMcVersion() {
return mcVersion.map(mc -> {
if (resolvedMcVersion != null)
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/parchmentmc/lodestone/LodestonePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@
import org.gradle.api.Plugin;
import org.gradle.api.Project;

/**
* LodestonePlugin is a Gradle plugin that applies the Lodestone functionality to a project.
* It implements the Plugin interface to define the plugin behavior when applied to a project.
*/
public class LodestonePlugin implements Plugin<Project> {

/**
* Applies the Lodestone plugin functionality to the specified Gradle project.
* It creates and configures a LodestoneExtension for the project.
*
* @param project The Gradle project to apply the plugin to.
*/
public void apply(Project project) {
LodestoneExtension extension = project.getExtensions().create("lodestone", LodestoneExtension.class, project);
}
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/org/parchmentmc/lodestone/asm/CodeCleaner.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,38 @@

public class CodeCleaner {

/**
* The CodeTree which holds the various classes and their mutable metadata representations.
*/
private final CodeTree codeTree;

/**
* Main Constructor for CodeCleaner
*
* @param codeTree The CodeTree object being read.
*/
public CodeCleaner(final CodeTree codeTree) {
this.codeTree = codeTree;
}

/**
* Grabs the name of the class to be cleaned from the mutable metadata, and passes it to the other implementation.
*
* @param classMetadata The mutable class metadata being passed in.
*/
public void cleanClass(final MutableClassInfo classMetadata) {
doCleanClass(
classMetadata.getName()
);
}

/**
* Cleans up the metadata for a class.
* The method does this by resolving bouncer methods and resolving abstract methods.
* This method also resolves record classes.
*
* @param className The name of the class being cleaned.
*/
private void doCleanClass(final String className) {
MutableClassInfo info = codeTree.getClassMetadataFor(className);
if (info == null || info.isResolved())
Expand Down Expand Up @@ -64,6 +84,13 @@ private void doCleanClass(final String className) {
info.setResolved(true);
}

/**
* Recursively walks up the class hierarchy to find the final implementation of a method by following bouncer methods.
*
* @param methodMetadata The mutable method metadata.
* @param className The name of the class that pertains to the method.
* @return Returns a mutable method reference metadata.
*/
private MutableMethodReferenceInfo doWalkBouncers(final MutableMethodInfo methodMetadata, String className) {
final MutableClassInfo classMetadata = codeTree.getClassMetadataFor(className);
if (!classMetadata.getMethods().isEmpty()) {
Expand Down Expand Up @@ -136,10 +163,26 @@ private MutableMethodReferenceInfo doWalkBouncers(final MutableMethodInfo method
return null;
}

/**
* Used to find the all methods that override the given method within the class hierarchy.
* Providing an empty set of method references.
*
* @param methodMetadata The mutable method metadata.
* @param ownerName The name of the owning class.
* @return Returns a Set of method references of overrides.
*/
private Set<MutableMethodReferenceInfo> findOverrides(MutableMethodInfo methodMetadata, String ownerName) {
return doFindOverrides(methodMetadata, ownerName, new LinkedHashSet<>());
}

/**
* Used to find the all methods that override the given method within the class hierarchy.
*
* @param methodMetadata The mutable method metadata.
* @param className The name of the class that the method exists in.
* @param overrides A Set of override method references.
* @return Returns a Set of method references of overrides.
*/
private Set<MutableMethodReferenceInfo> doFindOverrides(MutableMethodInfo methodMetadata, String className, Set<MutableMethodReferenceInfo> overrides) {
if (methodMetadata.isStatic() || methodMetadata.isPrivate() || methodMetadata.getMethod().getName().startsWith("<")) {
return overrides;
Expand Down Expand Up @@ -191,6 +234,13 @@ private Set<MutableMethodReferenceInfo> doFindOverrides(MutableMethodInfo method
return overrides;
}

/**
* Finds the first concrete implementation of the given method within the class hierarchy.
*
* @param mtd The method metadata.
* @param owner The name of the class that potentially overrides the method as its arguments
* @return Returns the first found method override reference.
*/
private MutableMethodReferenceInfo doFindFirstOverride(MutableMethodInfo mtd, String owner) {
if (mtd.isStatic() || mtd.isPrivate() || mtd.getMethod().getName().startsWith("<"))
return null;
Expand Down Expand Up @@ -238,6 +288,12 @@ private MutableMethodReferenceInfo doFindFirstOverride(MutableMethodInfo mtd, St
return null;
}

/**
* Resolves abstract methods in the class hierarchy, it does this by identifying the abstract methods
* concrete implementations and creating appropriate method references.
*
* @param cls The class metadata for trying to resolve the abstract root class.
*/
private void resolveAbstract(MutableClassInfo cls) {
Map<String, String> abs = new HashMap<>();
Set<String> known = new TreeSet<>();
Expand Down Expand Up @@ -308,6 +364,11 @@ private void resolveAbstract(MutableClassInfo cls) {
}
}

/**
* Copies over the record getters to the record info.
*
* @param mutableClassInfo The class metadata for trying to copy over the record getters.
*/
private void resolveRecord(MutableClassInfo mutableClassInfo) {
if (!mutableClassInfo.isRecord() || mutableClassInfo.getRecords().isEmpty() || mutableClassInfo.getFields().isEmpty())
return;
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/parchmentmc/lodestone/asm/CodeTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,26 @@
import java.util.zip.ZipInputStream;

public class CodeTree {

private final Set<String> noneLibraryClasses = new LinkedHashSet<>();
private final Map<String, byte[]> sources = new HashMap<>();

/**
* A map consisting of the class string identifier as the key and the Mutable class metadata as the value.
*/
private final Map<String, MutableClassInfo> parsedClasses = new HashMap<>();

public Set<String> getNoneLibraryClasses() {
return noneLibraryClasses;
}

/**
* Loads all class files for a given file path and stores them in the 'sources' map as byte arrays.
*
* @param path The file path to the file being loaded.
* @param library If the loaded file is a library or not.
* @throws IOException Throws an IOException if it couldn't read the file using the ZipInputStream.
*/
public final void load(final Path path, final boolean library) throws IOException {
try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(path))) {
ZipEntry entry;
Expand All @@ -41,6 +52,12 @@ public final void load(final Path path, final boolean library) throws IOExceptio
}
}

/**
* Retrieves the metadata for a given class name, creating it if necessary, and returns a MutableClassInfo object.
*
* @param cls The class identifier name.
* @return Returns the mutable metadata for the class.
*/
public MutableClassInfo getClassMetadataFor(String cls) {
MutableClassInfo classMetadata = parsedClasses.get(cls);
if (classMetadata == null) {
Expand All @@ -67,6 +84,13 @@ private MutableClassInfo buildClass(final ClassNode classNode) {
return new MutableClassInfo(classNode);
}

/**
* Reads an InputStream fully and returns the data as a byte array.
*
* @param is The input stream thats being read.
* @return Returns the read file in the form of a byte array of data.
* @throws IOException Throws an IOException if the data cannot be read.
*/
private static byte[] readStreamFully(InputStream is) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(Math.max(8192, is.available()));
byte[] buffer = new byte[8192];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.parchmentmc.lodestone.asm;

public class MutableBouncerInfo {

private final MutableMethodReferenceInfo target;
private MutableMethodReferenceInfo owner;

private MutableMethodReferenceInfo owner;

public MutableBouncerInfo(MutableMethodReferenceInfo target) {
this.target = target;
}
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/parchmentmc/lodestone/asm/MutableClassInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public class MutableClassInfo implements MutableSecuredObjectInfo {
private final boolean isRecord;
private boolean resolved = false;

/**
* Main Constructor
*
* @param node The class node being parsed into metadata.
*/
MutableClassInfo(ClassNode node) {
this.name = node.name;
this.superName = "java/lang/Object".equals(node.superName) ? null : node.superName;
Expand Down Expand Up @@ -72,6 +77,13 @@ public class MutableClassInfo implements MutableSecuredObjectInfo {
}
}

/**
* Returns the target method handle of the lambda expression represented by the given InvokeDynamicInsnNode.
*
* @param idn the InvokeDynamicInsnNode representing the lambda expression
* @return the target method handle of the lambda expression, or null if the given InvokeDynamicInsnNode does not represent a lambda expression
* @throws NullPointerException if the given InvokeDynamicInsnNode is null
*/
private Handle getLambdaTarget(InvokeDynamicInsnNode idn) {
if (LAMBDA_METAFACTORY.equals(idn.bsm) && idn.bsmArgs != null && idn.bsmArgs.length == 3 && idn.bsmArgs[1] instanceof Handle) {
return ((Handle) idn.bsmArgs[1]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
import org.parchmentmc.lodestone.asm.MutableBouncerInfo;

public class BouncingTargetConverter {

/**
* Converts the given MutableBouncerInfo object into a BouncingTargetMetadata object.
*
* @param bouncerInfo the MutableBouncerInfo object to convert
* @return a BouncingTargetMetadata object representing the converted MutableBouncerInfo object, or null if the input is null
* @throws ReferenceConversionException if an error occurs while converting a method reference in the MutableBouncerInfo object
*/
public BouncingTargetMetadata convert(final MutableBouncerInfo bouncerInfo) {
final ReferenceConverter methodReferenceConverter = new ReferenceConverter();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@

public class ClassConverter {

/**
* Converts the given MutableClassInfo object into a ClassMetadata object.
*
* @param classInfo the MutableClassInfo object to convert
* @return a ClassMetadata object representing the converted MutableClassInfo object
* @throws ReferenceConversionException if an error occurs while converting a reference in the MutableClassInfo object
*/
public ClassMetadata convert(final MutableClassInfo classInfo) {
final MethodConverter methodConverter = new MethodConverter();
final FieldConverter fieldConverter = new FieldConverter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
import org.parchmentmc.lodestone.asm.MutableFieldInfo;

public class FieldConverter {

/**
* Converts the given MutableFieldInfo object into a FieldMetadata object for the specified class.
*
* @param classInfo the MutableClassInfo object representing the class that the field belongs to
* @param fieldInfo the MutableFieldInfo object to convert
* @return a FieldMetadata object representing the converted MutableFieldInfo object
*/
public FieldMetadata convert(final MutableClassInfo classInfo, final MutableFieldInfo fieldInfo) {
return FieldMetadataBuilder.create()
.withName(NamedBuilder.create().withObfuscated(fieldInfo.getName()).build())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
import org.parchmentmc.lodestone.asm.MutableMethodInfo;

public class MethodConverter {

/**
* Converts the given MutableMethodInfo object into a MethodMetadata object for the specified class.
*
* @param classInfo the MutableClassInfo object representing the class that the method belongs to
* @param mutableMethodInfo the MutableMethodInfo object to convert
* @return a MethodMetadata object representing the converted MutableMethodInfo object
* @throws ReferenceConversionException if an error occurs while converting a reference in the MutableMethodInfo object
*/
public MethodMetadata convert(final MutableClassInfo classInfo, final MutableMethodInfo mutableMethodInfo) {
final ReferenceConverter methodReferenceConverter = new ReferenceConverter();
final BouncingTargetConverter bouncingTargetConverter = new BouncingTargetConverter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
import java.util.Iterator;

public class RecordConverter {

/**
* Converts the given MutableRecordInfo object into a RecordMetadata object for the specified class.
*
* @param classInfo the MutableClassInfo object representing the class that the record belongs to
* @param recordInfo the MutableRecordInfo object to convert
* @return a RecordMetadata object representing the converted MutableRecordInfo object
* @throws ReferenceConversionException if an error occurs while converting a reference in the MutableRecordInfo object
*/
public RecordMetadata convert(final MutableClassInfo classInfo, final MutableRecordInfo recordInfo) {
final ReferenceConverter referenceConverter = new ReferenceConverter();

Expand All @@ -35,6 +44,12 @@ public RecordMetadata convert(final MutableClassInfo classInfo, final MutableRec
.build();
}

/**
* Returns the MutableMethodReferenceInfo object representing the getter for the given MutableFieldInfo object.
*
* @param fieldInfo the MutableFieldInfo object to get the getter for
* @return the MutableMethodReferenceInfo object representing the getter for the given MutableFieldInfo object, or null if no getter is found
*/
private static MutableMethodReferenceInfo getGetter(MutableFieldInfo fieldInfo) {
final Iterator<MutableMethodReferenceInfo> iterator = fieldInfo.getGetters().iterator();
MutableMethodReferenceInfo result = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
import org.parchmentmc.lodestone.asm.MutableMethodReferenceInfo;

public class ReferenceConverter {

/**
* Converts the given MutableMethodReferenceInfo object into a Reference object.
*
* @param refInfo the MutableMethodReferenceInfo object to convert
* @return a Reference object representing the converted MutableMethodReferenceInfo object, or null if the input is null
*/
public Reference convert(final MutableMethodReferenceInfo refInfo) {
if (refInfo == null)
return null;
Expand Down
Loading