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

org.aion.avm.ArrayUtil Maven / Gradle / Ivy

There is a newer version: 0.9.6
Show newest version
package org.aion.avm;

import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import i.PackageConstants;
import i.RuntimeAssertionError;

public final class ArrayUtil {
    private static final String DOT_PREFIX = PackageConstants.kArrayWrapperDotPrefix;
    private static final String SLASH_PREFIX = PackageConstants.kArrayWrapperSlashPrefix;

    private static final Pattern PRE_RENAME_PRIMITIVE_1D = Pattern.compile("^\\[[IBZCFSJD]$");
    private static final Pattern PRE_RENAME_PRIMITIVE_MD = Pattern.compile("^\\[{2,}[IBZCFSJD]$");
    private static final Pattern PRE_RENAME_OBJECT = Pattern.compile("^\\[+L.+");
    private static final Pattern POST_RENAME_CONCRETE_DOT = Pattern.compile("^" + PackageConstants.kArrayWrapperDotPrefix + "\\$+L.+");
    private static final Pattern POST_RENAME_CONCRETE_SLASH = Pattern.compile("^" + PackageConstants.kArrayWrapperSlashPrefix + "\\$+L.+");
    private static final Pattern POST_RENAME_UNIFYING_DOT = Pattern.compile("^" + PackageConstants.kArrayWrapperUnifyingDotPrefix + "_+L.+");
    private static final Pattern POST_RENAME_UNIFYING_SLASH = Pattern.compile("^" + PackageConstants.kArrayWrapperUnifyingSlashPrefix + "_+L.+");

    private static Set postRenamePrimitiveSimpleNames = Stream.of(
        a.IntArray.class.getSimpleName(),
        a.LongArray.class.getSimpleName(),
        a.ByteArray.class.getSimpleName(),
        a.BooleanArray.class.getSimpleName(),
        a.ShortArray.class.getSimpleName(),
        a.DoubleArray.class.getSimpleName(),
        a.FloatArray.class.getSimpleName(),
        a.CharArray.class.getSimpleName())
        .collect(Collectors.toSet());

    private static Set primitiveSignifiers = Stream.of('I', 'J', 'Z', 'B', 'S', 'D', 'F', 'C').collect(Collectors.toSet());

    public static boolean isPreRenameSingleDimensionPrimitiveArray(String array) {
        RuntimeAssertionError.assertTrue(array != null);
        return PRE_RENAME_PRIMITIVE_1D.matcher(array).matches();
    }

    public static boolean isPreRenameMultiDimensionPrimitiveArray(String array) {
        RuntimeAssertionError.assertTrue(array != null);
        return PRE_RENAME_PRIMITIVE_MD.matcher(array).matches();
    }

    public static boolean isPreRenamePrimitiveArray(String array) {
        return isPreRenameSingleDimensionPrimitiveArray(array) || isPreRenameMultiDimensionPrimitiveArray(array);
    }

    public static boolean isPreRenameObjectArray(String array) {
        RuntimeAssertionError.assertTrue(array != null);
        return PRE_RENAME_OBJECT.matcher(array).matches();
    }

    public static boolean isPreRenameArray(String array) {
        return isPreRenamePrimitiveArray(array) || isPreRenameObjectArray(array);
    }

    public static boolean isPostRenameSingleDimensionPrimitiveArray(NameStyle style, String array) {
        String unwantedCharacter = (style == NameStyle.DOT_NAME) ? "/" : ".";
        RuntimeAssertionError.assertTrue(!array.contains(unwantedCharacter));

        String prefix = (style == NameStyle.DOT_NAME) ? DOT_PREFIX : SLASH_PREFIX;

        if (!array.startsWith(prefix)) {
            return false;
        }

        String strippedName = array.substring(prefix.length());
        return postRenamePrimitiveSimpleNames.contains(strippedName);
    }

    public static boolean isPostRenameMultiDimensionPrimitiveArray(NameStyle style, String array) {
        String unwantedCharacter = (style == NameStyle.DOT_NAME) ? "/" : ".";
        RuntimeAssertionError.assertTrue(!array.contains(unwantedCharacter));

        String prefix = ((style == NameStyle.DOT_NAME) ? DOT_PREFIX : SLASH_PREFIX);
        if (!array.startsWith(prefix)) {
            return false;
        }

        String strippedName = array.substring(prefix.length());
        int dimension = numberOfLeading('$', strippedName);
        if (dimension < 1) {
            return false;
        }

        char lastChar = strippedName.charAt(strippedName.length() - 1);
        return (strippedName.length() == dimension + 1) && (primitiveSignifiers.contains(lastChar));
    }

    public static boolean isPostRenamePrimitiveArray(NameStyle style, String array) {
        return isPostRenameSingleDimensionPrimitiveArray(style, array) || isPostRenameMultiDimensionPrimitiveArray(style, array);
    }

    public static boolean isPostRenameConcreteTypeObjectArray(NameStyle style, String array) {
        RuntimeAssertionError.assertTrue(style != null);
        RuntimeAssertionError.assertTrue(array != null);
        return (style == NameStyle.DOT_NAME) ? POST_RENAME_CONCRETE_DOT.matcher(array).matches() : POST_RENAME_CONCRETE_SLASH.matcher(array).matches();
    }

    public static boolean isPostRenameUnifyingTypeObjectArray(NameStyle style, String array) {
        RuntimeAssertionError.assertTrue(style != null);
        RuntimeAssertionError.assertTrue(array != null);
        return (style == NameStyle.DOT_NAME) ? POST_RENAME_UNIFYING_DOT.matcher(array).matches() : POST_RENAME_UNIFYING_SLASH.matcher(array).matches();
    }

    public static boolean isPostRenameObjectArray(NameStyle style, String array) {
        return isPostRenameConcreteTypeObjectArray(style, array) || isPostRenameUnifyingTypeObjectArray(style, array);
    }

    public static boolean isPostRenameArray(NameStyle style, String array) {
        return isPostRenamePrimitiveArray(style, array) || isPostRenameObjectArray(style, array) || isSpecialPostRenameArray(style, array);
    }

    public static boolean isSpecialPostRenameArray(NameStyle style, String array) {
        String prefix = (style == NameStyle.DOT_NAME) ? PackageConstants.kArrayWrapperDotPrefix : PackageConstants.kArrayWrapperSlashPrefix;
        String internalPrefix = (style == NameStyle.DOT_NAME) ? PackageConstants.kInternalDotPrefix : PackageConstants.kInternalSlashPrefix;

        if (array.equals(prefix + "ObjectArray") || array.equals(internalPrefix + "IObjectArray") || array.equals(prefix + "Array") || array.equals(prefix + "IArray")) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean isSingleDimensionalPrimitiveArray(NameStyle style, String array) {
        return isPreRenameSingleDimensionPrimitiveArray(array) || isPostRenameSingleDimensionPrimitiveArray(style, array);
    }

    public static boolean isMultiDimensionalPrimitiveArray(NameStyle style, String array) {
        return isPreRenameMultiDimensionPrimitiveArray(array) || isPostRenameMultiDimensionPrimitiveArray(style, array);
    }

    public static boolean isPrimitiveArray(NameStyle style, String array) {
        return isPreRenamePrimitiveArray(array) || isPostRenamePrimitiveArray(style, array);
    }

    public static boolean isObjectArray(NameStyle style, String array) {
        return isPreRenameObjectArray(array) || isPostRenameObjectArray(style, array);
    }

    public static boolean isArray(NameStyle style, String array) {
        return isPreRenameArray(array) || isPostRenameArray(style, array);
    }

    /**
     * Returns the dimension of the provided pre-rename primitive array.
     */
    public static int dimensionOfPreRenamePrimitiveArray(String array) {
        RuntimeAssertionError.assertTrue(isPreRenamePrimitiveArray(array));
        return numberOfLeading('[', array);
    }

    /**
     * Returns the dimension of the provided pre-rename object array.
     */
    public static int dimensionOfPreRenameObjectArray(String array) {
        RuntimeAssertionError.assertTrue(isPreRenameObjectArray(array));
        return numberOfLeading('[', array);
    }

    public static int dimensionOfPreRenameArray(String array) {
        if (isPreRenamePrimitiveArray(array)) {
            return dimensionOfPreRenamePrimitiveArray(array);
        } else if (isPreRenameObjectArray(array)) {
            return dimensionOfPreRenameObjectArray(array);
        } else {
            throw RuntimeAssertionError.unreachable("Expected pre-rename array: " + array);
        }
    }

    private static int dimensionOfPostRenameMultiDimensionPrimitiveArray(NameStyle style, String array) {
        String unwrappedArray = ArrayRenamer.stripArrayWrapperPrefix(style, array);
        return numberOfLeading('$', unwrappedArray);
    }

    public static int dimensionOfPostRenamePrimitiveArray(NameStyle style, String array) {
        if (isPostRenameSingleDimensionPrimitiveArray(style, array)) {
            return 1;
        } else if (isPostRenameMultiDimensionPrimitiveArray(style, array)) {
            return dimensionOfPostRenameMultiDimensionPrimitiveArray(style, array);
        } else {
            throw RuntimeAssertionError.unreachable("Expected post-rename primitive array: " + array);
        }
    }

    private static int dimensionOfPostRenameConcreteTypeObjectArray(NameStyle style, String array) {
        String unwrappedArray = ArrayRenamer.stripArrayWrapperPrefix(style, array);
        return numberOfLeading('$', unwrappedArray);
    }

    private static int dimensionOfPostRenameUnifyingTypeObjectArray(NameStyle style, String array) {
        String unwrappedArray = ArrayRenamer.stripArrayWrapperPrefix(style, array);
        return numberOfLeading('_', unwrappedArray);
    }

    public static int dimensionOfPostRenameObjectArray(NameStyle style, String array) {
        if (isPostRenameConcreteTypeObjectArray(style, array)) {
            return dimensionOfPostRenameConcreteTypeObjectArray(style, array);
        } else if (isPostRenameUnifyingTypeObjectArray(style, array)) {
            return dimensionOfPostRenameUnifyingTypeObjectArray(style, array);
        } else {
            throw RuntimeAssertionError.unreachable("Expected post-rename object array: " + array);
        }
    }

    public static int dimensionOfPostRenameArray(NameStyle style, String array) {
        if (isPostRenamePrimitiveArray(style, array)) {
            return dimensionOfPostRenamePrimitiveArray(style, array);
        } else if (isPostRenameObjectArray(style, array)) {
            return dimensionOfPostRenameObjectArray(style, array);
        } else {
            throw RuntimeAssertionError.unreachable("Expected post-rename array: " + array);
        }
    }

    public static int dimensionOfArray(NameStyle style, String array) {
        if (isPreRenameArray(array)) {
            return dimensionOfPreRenameArray(array);
        } else if (isPostRenameArray(style, array)) {
            return dimensionOfPostRenameArray(style, array);
        } else {
            throw RuntimeAssertionError.unreachable("Expected array: " + array);
        }
    }

    private static int numberOfLeading(char leadingChar, String string) {
        int count = 0;

        for (int i = 0; i < string.length(); i++) {
            if (string.charAt(i) != leadingChar) {
                return count;
            }
            count++;
        }

        return count;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy