Search in sources :

Example 1 with Dist

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;
}
Also used : AnnotationNode(org.objectweb.asm.tree.AnnotationNode) OnlyIn(net.minecraftforge.api.distmarker.OnlyIn) MethodVisitor(org.objectweb.asm.MethodVisitor) OnlyIns(net.minecraftforge.api.distmarker.OnlyIns) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Type(org.objectweb.asm.Type) ArrayList(java.util.ArrayList) Dist(net.minecraftforge.api.distmarker.Dist) MethodNode(org.objectweb.asm.tree.MethodNode) Marker(org.apache.logging.log4j.Marker) EnumSet(java.util.EnumSet) Opcodes(org.objectweb.asm.Opcodes) Iterator(java.util.Iterator) ILaunchPluginService(cpw.mods.modlauncher.serviceapi.ILaunchPluginService) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Consumer(java.util.function.Consumer) Handle(org.objectweb.asm.Handle) List(java.util.List) MarkerManager(org.apache.logging.log4j.MarkerManager) Logger(org.apache.logging.log4j.Logger) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) FieldNode(org.objectweb.asm.tree.FieldNode) ClassNode(org.objectweb.asm.tree.ClassNode) Collections(java.util.Collections) LogManager(org.apache.logging.log4j.LogManager) FieldNode(org.objectweb.asm.tree.FieldNode) Handle(org.objectweb.asm.Handle) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode)

Aggregations

Streams (com.google.common.collect.Streams)1 ILaunchPluginService (cpw.mods.modlauncher.serviceapi.ILaunchPluginService)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 EnumSet (java.util.EnumSet)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Objects (java.util.Objects)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 Consumer (java.util.function.Consumer)1 Collectors (java.util.stream.Collectors)1 Dist (net.minecraftforge.api.distmarker.Dist)1 OnlyIn (net.minecraftforge.api.distmarker.OnlyIn)1 OnlyIns (net.minecraftforge.api.distmarker.OnlyIns)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 Marker (org.apache.logging.log4j.Marker)1 MarkerManager (org.apache.logging.log4j.MarkerManager)1 Handle (org.objectweb.asm.Handle)1 MethodVisitor (org.objectweb.asm.MethodVisitor)1