All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.llamalad7.mixinextras.injector.IntLikeBehaviour Maven / Gradle / Ivy

package com.llamalad7.mixinextras.injector;

import com.llamalad7.mixinextras.utils.CompatibilityHelper;
import com.llamalad7.mixinextras.expression.impl.utils.ExpressionASMUtils;
import org.objectweb.asm.Type;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo;

import java.util.Arrays;

public abstract class IntLikeBehaviour {
    private IntLikeBehaviour() {
    }

    public Type transform(InjectionInfo info, Type expected, Type handler) {
        if (!expected.getDescriptor().contains(ExpressionASMUtils.INTLIKE_TYPE.getDescriptor())) {
            return expected;
        }
        return transformImpl(info, expected, handler);
    }

    protected abstract Type transformImpl(InjectionInfo info, Type expected, Type handler);

    protected Type replaceIntLike(InjectionInfo info, Type desc, Type replacement) {
        if (!ExpressionASMUtils.isIntLike(replacement)) {
            throw CompatibilityHelper.makeInvalidInjectionException(
                    info,
                    String.format(
                            "Expected int-like type (boolean, byte, char, short, int), got %s",
                            replacement
                    )
            );
        }
        Type returnType = desc.getReturnType();
        if (returnType.equals(ExpressionASMUtils.INTLIKE_TYPE)) {
            returnType = replacement;
        }
        Type[] args = Arrays.stream(desc.getArgumentTypes())
                .map(it -> it.equals(ExpressionASMUtils.INTLIKE_TYPE) ? replacement : it)
                .toArray(Type[]::new);
        return Type.getMethodType(returnType, args);
    }

    public static class MatchReturnType extends IntLikeBehaviour {
        public static final MatchReturnType INSTANCE = new MatchReturnType();

        @Override
        public Type transformImpl(InjectionInfo info, Type expected, Type handler) {
            return replaceIntLike(info, expected, handler.getReturnType());
        }
    }

    public static class MatchArgType extends IntLikeBehaviour {
        private final int index;

        public MatchArgType(int index) {
            this.index = index;
        }

        @Override
        public Type transformImpl(InjectionInfo info, Type expected, Type handler) {
            if (index >= handler.getArgumentTypes().length) {
                throw CompatibilityHelper.makeInvalidInjectionException(
                        info,
                        String.format(
                                "Expected int-like type for arg %s (boolean, byte, char, short, int), signature was %s",
                                index, handler.getDescriptor()
                        )
                );
            }
            return replaceIntLike(info, expected, handler.getArgumentTypes()[index]);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy