use of net.minecraftforge.api.distmarker.Dist in project MinecraftForge by MinecraftForge.
the class RuntimeDistCleaner method processClassWithFlags.
@Override
public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason) {
AtomicBoolean changes = new AtomicBoolean();
if (remove(classNode.visibleAnnotations, DIST)) {
LOGGER.fatal(DISTXFORM, "Attempted to load class {} for invalid dist {}", classNode.name, DIST);
throw new RuntimeException("Attempted to load class " + classNode.name + " for invalid dist " + DIST);
}
if (classNode.interfaces != null) {
unpack(classNode.visibleAnnotations).stream().filter(ann -> Objects.equals(ann.desc, ONLYIN)).filter(ann -> ann.values.indexOf("_interface") != -1).filter(ann -> !Objects.equals(((String[]) ann.values.get(ann.values.indexOf("value") + 1))[1], DIST)).map(ann -> ((Type) ann.values.get(ann.values.indexOf("_interface") + 1)).getInternalName()).forEach(intf -> {
if (classNode.interfaces.remove(intf)) {
LOGGER.debug(DISTXFORM, "Removing Interface: {} implements {}", classNode.name, intf);
changes.compareAndSet(false, true);
}
});
// Remove Class level @OnlyIn/@OnlyIns annotations, this is important if anyone gets ambitious and tries to reflect an annotation with _interface set.
if (classNode.visibleAnnotations != null) {
Iterator<AnnotationNode> itr = classNode.visibleAnnotations.iterator();
while (itr.hasNext()) {
AnnotationNode ann = itr.next();
if (Objects.equals(ann.desc, ONLYIN) || Objects.equals(ann.desc, ONLYINS)) {
LOGGER.debug(DISTXFORM, "Removing Class Annotation: {} @{}", classNode.name, ann.desc);
itr.remove();
changes.compareAndSet(false, true);
}
}
}
}
Iterator<FieldNode> fields = classNode.fields.iterator();
while (fields.hasNext()) {
FieldNode field = fields.next();
if (remove(field.visibleAnnotations, DIST)) {
LOGGER.debug(DISTXFORM, "Removing field: {}.{}", classNode.name, field.name);
fields.remove();
changes.compareAndSet(false, true);
}
}
LambdaGatherer lambdaGatherer = new LambdaGatherer();
Iterator<MethodNode> methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = methods.next();
if (remove(method.visibleAnnotations, DIST)) {
LOGGER.debug(DISTXFORM, "Removing method: {}.{}{}", classNode.name, method.name, method.desc);
methods.remove();
lambdaGatherer.accept(method);
changes.compareAndSet(false, true);
}
}
// remove dynamic synthetic lambda methods that are inside of removed methods
for (List<Handle> dynamicLambdaHandles = lambdaGatherer.getDynamicLambdaHandles(); !dynamicLambdaHandles.isEmpty(); dynamicLambdaHandles = lambdaGatherer.getDynamicLambdaHandles()) {
lambdaGatherer = new LambdaGatherer();
methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = methods.next();
if ((method.access & Opcodes.ACC_SYNTHETIC) == 0)
continue;
for (Handle dynamicLambdaHandle : dynamicLambdaHandles) {
if (method.name.equals(dynamicLambdaHandle.getName()) && method.desc.equals(dynamicLambdaHandle.getDesc())) {
LOGGER.debug(DISTXFORM, "Removing lambda method: {}.{}{}", classNode.name, method.name, method.desc);
methods.remove();
lambdaGatherer.accept(method);
changes.compareAndSet(false, true);
}
}
}
}
return changes.get() ? ComputeFlags.SIMPLE_REWRITE : ComputeFlags.NO_REWRITE;
}
Aggregations