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

org.plumelib.bcelutil.JvmUtil Maven / Gradle / Ivy

There is a newer version: 1.2.2
Show newest version
package org.plumelib.bcelutil;

import java.util.HashMap;
import java.util.StringTokenizer;
import org.checkerframework.checker.index.qual.Positive;
import org.checkerframework.checker.signature.qual.BinaryName;
import org.checkerframework.checker.signature.qual.ClassGetName;
import org.checkerframework.checker.signature.qual.FieldDescriptor;
import org.checkerframework.checker.signature.qual.PrimitiveType;

/**
 * Utility functions for working with the JVM.
 *
 * 

Currently contains conversion utilities between Java and JVM string formats, for types and * signatures. * * @deprecated Use org.plumelib.reflection.Signatures */ @Deprecated public final class JvmUtil { /** A map from Java primitive type name (such as "int") to field descriptor (such as "I"). */ private static HashMap<@PrimitiveType String, @FieldDescriptor String> primitiveToFieldDescriptor = new HashMap<>(8); static { primitiveToFieldDescriptor.put("boolean", "Z"); primitiveToFieldDescriptor.put("byte", "B"); primitiveToFieldDescriptor.put("char", "C"); primitiveToFieldDescriptor.put("double", "D"); primitiveToFieldDescriptor.put("float", "F"); primitiveToFieldDescriptor.put("int", "I"); primitiveToFieldDescriptor.put("long", "J"); primitiveToFieldDescriptor.put("short", "S"); } /** * Convert a binary name to a field descriptor. For example, convert "java.lang.Object[]" to * "[Ljava/lang/Object;" or "int" to "I" or "pkg.Outer$Inner" to "Lpkg/Outer$Inner;". * *

There are no binary names for primitives or array types. Nonetheless, this method works for * them. It converts "java.lang.Object[]" to "[Ljava/lang/Object;" or "int" to "I". * * @param classname name of the class, in binary class name format * @return name of the class, in field descriptor format */ @SuppressWarnings("signature") // conversion routine public static @FieldDescriptor String binaryNameToFieldDescriptor(@BinaryName String classname) { int dimensions = 0; String sansArray = classname; while (sansArray.endsWith("[]")) { dimensions++; sansArray = sansArray.substring(0, sansArray.length() - 2); } String result = primitiveToFieldDescriptor.get(sansArray); if (result == null) { result = "L" + sansArray + ";"; } for (int i = 0; i < dimensions; i++) { result = "[" + result; } return result.replace('.', '/'); } /** * Convert a primitive Java type name (e.g., "int", "double", etc.) to a field descriptor (e.g., * "I", "D", etc.). * * @param primitiveName name of the type, in Java format * @return name of the type, in field descriptor format * @throws IllegalArgumentException if primitiveName is not a valid primitive type name */ public static @FieldDescriptor String primitiveTypeNameToFieldDescriptor(String primitiveName) { String result = primitiveToFieldDescriptor.get(primitiveName); if (result == null) { throw new IllegalArgumentException("Not the name of a primitive type: " + primitiveName); } return result; } /** * Convert from a BinaryName to the format of {@link Class#getName()}. * *

There are no binary names for primitives or array types. Nonetheless, this method works for * them. It converts "java.lang.Object[]" to "[Ljava.lang.Object;" or "int" to "int". * * @param bn the binary name to convert * @return the class name, in Class.getName format */ @SuppressWarnings("signature") // conversion routine public static @ClassGetName String binaryNameToClassGetName(@BinaryName String bn) { if (bn.endsWith("[]")) { return binaryNameToFieldDescriptor(bn).replace('/', '.'); } else { return bn; } } /** * Convert from a FieldDescriptor to the format of {@link Class#getName()}. * * @param fd the class, in field descriptor format * @return the class name, in Class.getName format */ @SuppressWarnings("signature") // conversion routine public static @ClassGetName String fieldDescriptorToClassGetName(@FieldDescriptor String fd) { if (fd.startsWith("[")) { return fd.replace('/', '.'); } else { return fieldDescriptorToBinaryName(fd); } } /** * Convert a fully-qualified argument list from Java format to JVML format. For example, convert * "(java.lang.Integer[], int, java.lang.Integer[][])" to * "([Ljava/lang/Integer;I[[Ljava/lang/Integer;)". * * @param arglist an argument list, in Java format * @return argument list, in JVML format */ public static String arglistToJvm(String arglist) { if (!(arglist.startsWith("(") && arglist.endsWith(")"))) { throw new Error("Malformed arglist: " + arglist); } String result = "("; String commaSepArgs = arglist.substring(1, arglist.length() - 1); StringTokenizer argsTokenizer = new StringTokenizer(commaSepArgs, ",", false); while (argsTokenizer.hasMoreTokens()) { @SuppressWarnings("signature") // substring @BinaryName String arg = argsTokenizer.nextToken().trim(); result += binaryNameToFieldDescriptor(arg); } result += ")"; // System.out.println("arglistToJvm: " + arglist + " => " + result); return result; } /** A map from field descriptor (sach as "I") to Java primitive type (such as "int"). */ private static HashMap fieldDescriptorToPrimitive = new HashMap<>(8); static { fieldDescriptorToPrimitive.put("Z", "boolean"); fieldDescriptorToPrimitive.put("B", "byte"); fieldDescriptorToPrimitive.put("C", "char"); fieldDescriptorToPrimitive.put("D", "double"); fieldDescriptorToPrimitive.put("F", "float"); fieldDescriptorToPrimitive.put("I", "int"); fieldDescriptorToPrimitive.put("J", "long"); fieldDescriptorToPrimitive.put("S", "short"); } // does not convert "V" to "void". Should it? /** * Convert a field descriptor to a binary name. For example, convert "[Ljava/lang/Object;" to * "java.lang.Object[]" or "I" to "int". * * @param classname name of the type, in JVML format * @return name of the type, in Java format */ @SuppressWarnings("signature") // conversion routine public static @BinaryName String fieldDescriptorToBinaryName(String classname) { if (classname.equals("")) { throw new Error("Empty string passed to fieldDescriptorToBinaryName"); } int dimensions = 0; while (classname.startsWith("[")) { dimensions++; classname = classname.substring(1); } String result; if (classname.startsWith("L") && classname.endsWith(";")) { result = classname.substring(1, classname.length() - 1); } else { result = fieldDescriptorToPrimitive.get(classname); if (result == null) { throw new Error("Malformed base class: " + classname); } } for (int i = 0; i < dimensions; i++) { result += "[]"; } return result.replace('/', '.'); } /** * Convert an argument list from JVML format to Java format. For example, convert * "([Ljava/lang/Integer;I[[Ljava/lang/Integer;)" to "(java.lang.Integer[], int, * java.lang.Integer[][])". * *

The argument is the first part of a method descriptor. * * @param arglist an argument list, in JVML format * @return argument list, in Java format */ public static String arglistFromJvm(String arglist) { if (!(arglist.startsWith("(") && arglist.endsWith(")"))) { throw new Error("Malformed arglist: " + arglist); } String result = "("; @Positive int pos = 1; while (pos < arglist.length() - 1) { if (pos > 1) { result += ", "; } int nonarrayPos = pos; while (arglist.charAt(nonarrayPos) == '[') { nonarrayPos++; if (nonarrayPos >= arglist.length()) { throw new Error("Malformed arglist: " + arglist); } } char c = arglist.charAt(nonarrayPos); if (c == 'L') { int semicolonPos = arglist.indexOf(';', nonarrayPos); if (semicolonPos == -1) { throw new Error("Malformed arglist: " + arglist); } @SuppressWarnings("signature") // string parsing @FieldDescriptor String fieldDescriptor = arglist.substring(pos, semicolonPos + 1); result += fieldDescriptorToBinaryName(fieldDescriptor); pos = semicolonPos + 1; } else { @SuppressWarnings("signature") // string parsing @FieldDescriptor String fieldDescriptor = arglist.substring(pos, nonarrayPos + 1); String maybe = fieldDescriptorToBinaryName(fieldDescriptor); if (maybe == null) { // return null; throw new Error("Malformed arglist: " + arglist); } result += maybe; pos = nonarrayPos + 1; } } return result + ")"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy