Convert ClassPath to Kotlin

pull/48/head
Graham 4 years ago
parent 862d4a3504
commit d2bd8c69f4
  1. 207
      asm/src/main/java/dev/openrs2/asm/classpath/ClassPath.java
  2. 194
      asm/src/main/java/dev/openrs2/asm/classpath/ClassPath.kt

@ -1,207 +0,0 @@
package dev.openrs2.asm.classpath;
import java.util.HashMap;
import java.util.Map;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import dev.openrs2.asm.MemberDesc;
import dev.openrs2.asm.MemberRef;
import dev.openrs2.util.collect.DisjointSet;
import dev.openrs2.util.collect.ForestDisjointSet;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.ClassNode;
public final class ClassPath {
private final ClassLoader runtime;
private final ImmutableList<Library> dependencies, libraries;
private final Map<String, ClassMetadata> cache = new HashMap<>();
public ClassPath(ClassLoader runtime, ImmutableList<Library> dependencies, ImmutableList<Library> libraries) {
this.runtime = runtime;
this.dependencies = dependencies;
this.libraries = libraries;
}
public ImmutableList<Library> getLibraries() {
return libraries;
}
public ImmutableList<ClassMetadata> getLibraryClasses() {
var classes = ImmutableList.<ClassMetadata>builder();
for (var library : libraries) {
for (var clazz : library) {
classes.add(get(clazz.name));
}
}
return classes.build();
}
public ClassMetadata get(String name) {
var metadata = cache.get(name);
if (metadata != null) {
return metadata;
}
for (var library : libraries) {
var clazz = library.get(name);
if (clazz != null) {
metadata = new AsmClassMetadata(this, clazz, false);
cache.put(name, metadata);
return metadata;
}
}
for (var library : dependencies) {
var clazz = library.get(name);
if (clazz != null) {
metadata = new AsmClassMetadata(this, clazz, true);
cache.put(name, metadata);
return metadata;
}
}
var reflectionName = name.replace('/', '.');
Class<?> clazz;
try {
clazz = runtime.loadClass(reflectionName);
} catch (ClassNotFoundException ex) {
throw new IllegalArgumentException("Unknown class " + name);
}
metadata = new ReflectionClassMetadata(this, clazz);
cache.put(name, metadata);
return metadata;
}
public ClassNode getNode(String name) {
for (var library : libraries) {
var clazz = library.get(name);
if (clazz != null) {
return clazz;
}
}
return null;
}
public void remap(Remapper remapper) {
for (var library : libraries) {
library.remap(remapper);
}
cache.clear();
}
public DisjointSet<MemberRef> createInheritedFieldSets() {
var disjointSet = new ForestDisjointSet<MemberRef>();
var ancestorCache = new HashMap<ClassMetadata, ImmutableSet<MemberDesc>>();
for (var library : libraries) {
for (var clazz : library) {
populateInheritedFieldSets(ancestorCache, disjointSet, get(clazz.name));
}
}
return disjointSet;
}
private ImmutableSet<MemberDesc> populateInheritedFieldSets(Map<ClassMetadata, ImmutableSet<MemberDesc>> ancestorCache, DisjointSet<MemberRef> disjointSet, ClassMetadata clazz) {
var ancestors = ancestorCache.get(clazz);
if (ancestors != null) {
return ancestors;
}
var ancestorsBuilder = ImmutableSet.<MemberDesc>builder();
var superClass = clazz.getSuperClass();
if (superClass != null) {
var fields = populateInheritedFieldSets(ancestorCache, disjointSet, superClass);
for (var field : fields) {
var partition1 = disjointSet.add(new MemberRef(clazz.getName(), field));
var partition2 = disjointSet.add(new MemberRef(superClass.getName(), field));
disjointSet.union(partition1, partition2);
}
ancestorsBuilder.addAll(fields);
}
for (var superInterface : clazz.getSuperInterfaces()) {
var fields = populateInheritedFieldSets(ancestorCache, disjointSet, superInterface);
for (var field : fields) {
var partition1 = disjointSet.add(new MemberRef(clazz.getName(), field));
var partition2 = disjointSet.add(new MemberRef(superInterface.getName(), field));
disjointSet.union(partition1, partition2);
}
ancestorsBuilder.addAll(fields);
}
for (var field : clazz.getFields()) {
disjointSet.add(new MemberRef(clazz.getName(), field));
ancestorsBuilder.add(field);
}
ancestors = ancestorsBuilder.build();
ancestorCache.put(clazz, ancestors);
return ancestors;
}
public DisjointSet<MemberRef> createInheritedMethodSets() {
var disjointSet = new ForestDisjointSet<MemberRef>();
var ancestorCache = new HashMap<ClassMetadata, ImmutableSet<MemberDesc>>();
for (var library : libraries) {
for (var clazz : library) {
populateInheritedMethodSets(ancestorCache, disjointSet, get(clazz.name));
}
}
return disjointSet;
}
private ImmutableSet<MemberDesc> populateInheritedMethodSets(Map<ClassMetadata, ImmutableSet<MemberDesc>> ancestorCache, DisjointSet<MemberRef> disjointSet, ClassMetadata clazz) {
var ancestors = ancestorCache.get(clazz);
if (ancestors != null) {
return ancestors;
}
var ancestorsBuilder = ImmutableSet.<MemberDesc>builder();
var superClass = clazz.getSuperClass();
if (superClass != null) {
var methods = populateInheritedMethodSets(ancestorCache, disjointSet, superClass);
for (var method : methods) {
var partition1 = disjointSet.add(new MemberRef(clazz.getName(), method));
var partition2 = disjointSet.add(new MemberRef(superClass.getName(), method));
disjointSet.union(partition1, partition2);
}
ancestorsBuilder.addAll(methods);
}
for (var superInterface : clazz.getSuperInterfaces()) {
var methods = populateInheritedMethodSets(ancestorCache, disjointSet, superInterface);
for (var method : methods) {
var partition1 = disjointSet.add(new MemberRef(clazz.getName(), method));
var partition2 = disjointSet.add(new MemberRef(superInterface.getName(), method));
disjointSet.union(partition1, partition2);
}
ancestorsBuilder.addAll(methods);
}
for (var method : clazz.getMethods()) {
disjointSet.add(new MemberRef(clazz.getName(), method));
ancestorsBuilder.add(method);
}
ancestors = ancestorsBuilder.build();
ancestorCache.put(clazz, ancestors);
return ancestors;
}
}

@ -0,0 +1,194 @@
package dev.openrs2.asm.classpath
import com.google.common.collect.ImmutableList
import dev.openrs2.asm.MemberDesc
import dev.openrs2.asm.MemberRef
import dev.openrs2.util.collect.DisjointSet
import dev.openrs2.util.collect.ForestDisjointSet
import org.objectweb.asm.commons.Remapper
import org.objectweb.asm.tree.ClassNode
class ClassPath(
private val runtime: ClassLoader,
private val dependencies: ImmutableList<Library>,
val libraries: List<Library>
) {
private val cache = mutableMapOf<String, ClassMetadata>()
val libraryClasses: List<ClassMetadata>
get() {
val classes = mutableListOf<ClassMetadata>()
for (library in libraries) {
for (clazz in library) {
classes.add(get(clazz.name))
}
}
return classes
}
operator fun get(name: String): ClassMetadata {
var metadata = cache[name]
if (metadata != null) {
return metadata
}
for (library in libraries) {
val clazz = library[name]
if (clazz != null) {
metadata = AsmClassMetadata(this, clazz, false)
cache[name] = metadata
return metadata
}
}
for (library in dependencies) {
val clazz = library[name]
if (clazz != null) {
metadata = AsmClassMetadata(this, clazz, true)
cache[name] = metadata
return metadata
}
}
val reflectionName = name.replace('/', '.')
val clazz = try {
runtime.loadClass(reflectionName)
} catch (ex: ClassNotFoundException) {
throw IllegalArgumentException("Unknown class $name")
}
metadata = ReflectionClassMetadata(this, clazz)
cache[name] = metadata
return metadata
}
fun getNode(name: String): ClassNode? {
for (library in libraries) {
val clazz = library[name]
if (clazz != null) {
return clazz
}
}
return null
}
fun remap(remapper: Remapper) {
for (library in libraries) {
library.remap(remapper)
}
cache.clear()
}
fun createInheritedFieldSets(): DisjointSet<MemberRef> {
val disjointSet = ForestDisjointSet<MemberRef>()
val ancestorCache = mutableMapOf<ClassMetadata, Set<MemberDesc>>()
for (library in libraries) {
for (clazz in library) {
populateInheritedFieldSets(ancestorCache, disjointSet, get(clazz.name))
}
}
return disjointSet
}
private fun populateInheritedFieldSets(
ancestorCache: MutableMap<ClassMetadata, Set<MemberDesc>>,
disjointSet: DisjointSet<MemberRef>,
clazz: ClassMetadata
): Set<MemberDesc> {
val ancestors = ancestorCache[clazz]
if (ancestors != null) {
return ancestors
}
val ancestorsBuilder = mutableSetOf<MemberDesc>()
val superClass = clazz.superClass
if (superClass != null) {
val fields = populateInheritedFieldSets(ancestorCache, disjointSet, superClass)
for (field in fields) {
val partition1 = disjointSet.add(MemberRef(clazz.name, field))
val partition2 = disjointSet.add(MemberRef(superClass.name, field))
disjointSet.union(partition1, partition2)
}
ancestorsBuilder.addAll(fields)
}
for (superInterface in clazz.superInterfaces) {
val fields = populateInheritedFieldSets(ancestorCache, disjointSet, superInterface)
for (field in fields) {
val partition1 = disjointSet.add(MemberRef(clazz.name, field))
val partition2 = disjointSet.add(MemberRef(superInterface.name, field))
disjointSet.union(partition1, partition2)
}
ancestorsBuilder.addAll(fields)
}
for (field in clazz.fields) {
disjointSet.add(MemberRef(clazz.name, field))
ancestorsBuilder.add(field)
}
ancestorCache[clazz] = ancestorsBuilder
return ancestorsBuilder
}
fun createInheritedMethodSets(): DisjointSet<MemberRef> {
val disjointSet = ForestDisjointSet<MemberRef>()
val ancestorCache = mutableMapOf<ClassMetadata, Set<MemberDesc>>()
for (library in libraries) {
for (clazz in library) {
populateInheritedMethodSets(ancestorCache, disjointSet, get(clazz.name))
}
}
return disjointSet
}
private fun populateInheritedMethodSets(
ancestorCache: MutableMap<ClassMetadata, Set<MemberDesc>>,
disjointSet: DisjointSet<MemberRef>,
clazz: ClassMetadata
): Set<MemberDesc> {
val ancestors = ancestorCache[clazz]
if (ancestors != null) {
return ancestors
}
val ancestorsBuilder = mutableSetOf<MemberDesc>()
val superClass = clazz.superClass
if (superClass != null) {
val methods = populateInheritedMethodSets(ancestorCache, disjointSet, superClass)
for (method in methods) {
val partition1 = disjointSet.add(MemberRef(clazz.name, method))
val partition2 = disjointSet.add(MemberRef(superClass.name, method))
disjointSet.union(partition1, partition2)
}
ancestorsBuilder.addAll(methods)
}
for (superInterface in clazz.superInterfaces) {
val methods = populateInheritedMethodSets(ancestorCache, disjointSet, superInterface)
for (method in methods) {
val partition1 = disjointSet.add(MemberRef(clazz.name, method))
val partition2 = disjointSet.add(MemberRef(superInterface.name, method))
disjointSet.union(partition1, partition2)
}
ancestorsBuilder.addAll(methods)
}
for (method in clazz.methods) {
disjointSet.add(MemberRef(clazz.name, method))
ancestorsBuilder.add(method)
}
ancestorCache[clazz] = ancestorsBuilder
return ancestorsBuilder
}
}
Loading…
Cancel
Save