blob: 82dd6f5e417abc3d018b5d0be8ac40514c4174d1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdi.internal;
import com.sun.jdi.ClassLoaderReference;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassNotPreparedException;
import com.sun.jdi.Type;
import com.sun.jdi.Value;
/**
* this class implements the corresponding interfaces declared by the JDI
* specification. See the com.sun.jdi package for more information.
*
*/
public abstract class TypeImpl extends AccessibleImpl implements Type {
/** Text representation of this type. */
protected String fName = null;
/** JNI-style signature for this type. */
protected String fSignature = null;
/**
* Creates new instance, used for REFERENCE types.
*/
protected TypeImpl(String description, VirtualMachineImpl vmImpl) {
super(description, vmImpl);
}
/**
* Creates new instance, used for PRIMITIVE types or VOID.
*/
protected TypeImpl(String description, VirtualMachineImpl vmImpl,
String name, String signature) {
super(description, vmImpl);
setName(name);
setSignature(signature);
}
/**
* @return Returns new instance based on signature and (if it is a
* ReferenceType) classLoader.
* @throws ClassNotLoadedException
* when type is a ReferenceType and it has not been loaded by
* the specified class loader.
*/
public static TypeImpl create(VirtualMachineImpl vmImpl, String signature,
ClassLoaderReference classLoader) throws ClassNotLoadedException {
// For void values, a VoidType is always returned.
if (isVoidSignature(signature))
return new VoidTypeImpl(vmImpl);
// For primitive variables, an appropriate PrimitiveType is always
// returned.
if (isPrimitiveSignature(signature))
return PrimitiveTypeImpl.create(vmImpl, signature);
// For object variables, the appropriate ReferenceType is returned if it
// has
// been loaded through the enclosing type's class loader.
return ReferenceTypeImpl.create(vmImpl, signature, classLoader);
}
/**
* Assigns name.
*/
public void setName(String name) {
fName = name;
}
/**
* Assigns signature.
*/
public void setSignature(String signature) {
fSignature = signature;
}
/**
* @return Returns description of Mirror object.
*/
@Override
public String toString() {
try {
return name();
} catch (ClassNotPreparedException e) {
return JDIMessages.TypeImpl__Unloaded_Type__1;
} catch (Exception e) {
return fDescription;
}
}
/**
* @return Create a null value instance of the type.
*/
public abstract Value createNullValue();
/**
* @return Returns text representation of this type.
*/
@Override
public String name() {
return fName;
}
/**
* @return JNI-style signature for this type.
*/
@Override
public String signature() {
return fSignature;
}
/**
* @return Returns modifier bits.
*/
@Override
public abstract int modifiers();
/**
* Converts a class name to a JNI signature.
*/
public static String classNameToSignature(String qualifiedName) {
// L<classname>; : fully-qualified-class
/*
* JNI signature examples: int[][] -> [[I long[] -> [J java.lang.String
* -> Ljava/lang/String; java.lang.String[] -> [Ljava/lang/String;
*/
StringBuilder signature = new StringBuilder();
int firstBrace = qualifiedName.indexOf('[');
if (firstBrace < 0) {
// Not an array type. Must be class type.
signature.append('L');
signature.append(qualifiedName.replace('.', '/'));
signature.append(';');
return signature.toString();
}
int index = 0;
while ((index = (qualifiedName.indexOf('[', index) + 1)) > 0) {
signature.append('[');
}
String name = qualifiedName.substring(0, firstBrace);
switch (name.charAt(0)) {
// Check for primitive array type
case 'b':
if (name.equals("byte")) { //$NON-NLS-1$
signature.append('B');
return signature.toString();
} else if (name.equals("boolean")) { //$NON-NLS-1$
signature.append('Z');
return signature.toString();
}
break;
case 'i':
if (name.equals("int")) { //$NON-NLS-1$
signature.append('I');
return signature.toString();
}
break;
case 'd':
if (name.equals("double")) { //$NON-NLS-1$
signature.append('D');
return signature.toString();
}
break;
case 's':
if (name.equals("short")) { //$NON-NLS-1$
signature.append('S');
return signature.toString();
}
break;
case 'c':
if (name.equals("char")) { //$NON-NLS-1$
signature.append('C');
return signature.toString();
}
break;
case 'l':
if (name.equals("long")) { //$NON-NLS-1$
signature.append('J');
return signature.toString();
}
break;
case 'f':
if (name.equals("float")) { //$NON-NLS-1$
signature.append('F');
return signature.toString();
}
break;
}
// Class type array
signature.append('L');
signature.append(name.replace('.', '/'));
signature.append(';');
return signature.toString();
}
/**
* Converts a JNI class signature to a name.
*/
public static String classSignatureToName(String signature) {
// L<classname>; : fully-qualified-class
return signature.substring(1, signature.length() - 1).replace('/', '.');
}
/**
* Converts a JNI array signature to a name.
*/
public static String arraySignatureToName(String signature) {
// [<type> : array of type <type>
if (signature.indexOf('[') < 0) {
return signature;
}
StringBuilder name = new StringBuilder();
String type = signature.substring(signature.lastIndexOf('[') + 1);
if (type.length() == 1 && isPrimitiveSignature(type)) {
name.append(getPrimitiveSignatureToName(type.charAt(0)));
} else {
name.append(classSignatureToName(type));
}
int index = 0;
while ((index = (signature.indexOf('[', index) + 1)) > 0) {
name.append('[').append(']');
}
return signatureToName(signature.substring(1)) + "[]"; //$NON-NLS-1$
}
/**
* @returns Returns Type Name, converted from a JNI signature.
*/
public static String signatureToName(String signature) {
// See JNI 1.1 Specification, Table 3-2 Java VM Type Signatures.
String primitive = getPrimitiveSignatureToName(signature.charAt(0));
if (primitive != null) {
return primitive;
}
switch (signature.charAt(0)) {
case 'V':
return "void"; //$NON-NLS-1$
case 'L':
return classSignatureToName(signature);
case '[':
return arraySignatureToName(signature);
case '(':
throw new InternalError(
JDIMessages.TypeImpl_Can__t_convert_method_signature_to_name_2);
}
throw new InternalError(JDIMessages.TypeImpl_Invalid_signature____10
+ signature + JDIMessages.TypeImpl___11); //
}
private static String getPrimitiveSignatureToName(char signature) {
switch (signature) {
case 'Z':
return "boolean"; //$NON-NLS-1$
case 'B':
return "byte"; //$NON-NLS-1$
case 'C':
return "char"; //$NON-NLS-1$
case 'S':
return "short"; //$NON-NLS-1$
case 'I':
return "int"; //$NON-NLS-1$
case 'J':
return "long"; //$NON-NLS-1$
case 'F':
return "float"; //$NON-NLS-1$
case 'D':
return "double"; //$NON-NLS-1$
default:
return null;
}
}
/**
* @returns Returns Jdwp Tag, converted from a JNI signature.
*/
public static byte signatureToTag(String signature) {
switch (signature.charAt(0)) {
case 'Z':
return BooleanValueImpl.tag;
case 'B':
return ByteValueImpl.tag;
case 'C':
return CharValueImpl.tag;
case 'S':
return ShortValueImpl.tag;
case 'I':
return IntegerValueImpl.tag;
case 'J':
return LongValueImpl.tag;
case 'F':
return FloatValueImpl.tag;
case 'D':
return DoubleValueImpl.tag;
case 'V':
return VoidValueImpl.tag;
case 'L':
return ObjectReferenceImpl.tag;
case '[':
return ArrayReferenceImpl.tag;
case '(':
throw new InternalError(
JDIMessages.TypeImpl_Can__t_covert_method_signature_to_tag___9
+ signature);
}
throw new InternalError(JDIMessages.TypeImpl_Invalid_signature____10
+ signature + JDIMessages.TypeImpl___11); //
}
/**
* @returns Returns true if signature is an primitive signature.
*/
public static boolean isPrimitiveSignature(String signature) {
switch (signature.charAt(0)) {
case 'Z':
case 'B':
case 'C':
case 'S':
case 'I':
case 'J':
case 'F':
case 'D':
return true;
}
return false;
}
/**
* @returns Returns true if signature is void signature.
*/
public static boolean isVoidSignature(String signature) {
return (signature.charAt(0) == 'V');
}
}