aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/bytecode/SignatureAttribute.java
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2012-06-17 15:01:27 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2012-06-17 15:01:27 +0000
commite2cfbeaed7be298c93251f6f9af480cdba84f68f (patch)
tree8b49af3c3a31cde77e252c5327900fbb0d628505 /src/main/javassist/bytecode/SignatureAttribute.java
parent08deb0e6bc17f84f6bda03a29a7c2d3a8610a1ef (diff)
downloadjavassist-e2cfbeaed7be298c93251f6f9af480cdba84f68f.tar.gz
javassist-e2cfbeaed7be298c93251f6f9af480cdba84f68f.zip
implemented JASSIST-170
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@639 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist/bytecode/SignatureAttribute.java')
-rw-r--r--src/main/javassist/bytecode/SignatureAttribute.java315
1 files changed, 297 insertions, 18 deletions
diff --git a/src/main/javassist/bytecode/SignatureAttribute.java b/src/main/javassist/bytecode/SignatureAttribute.java
index 08d7f3b8..9e6921c5 100644
--- a/src/main/javassist/bytecode/SignatureAttribute.java
+++ b/src/main/javassist/bytecode/SignatureAttribute.java
@@ -38,7 +38,7 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
- * Constructs a Signature attribute.
+ * Constructs a <code>Signature</code> attribute.
*
* @param cp a constant pool table.
* @param signature the signature represented by this attribute.
@@ -53,17 +53,18 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
- * Returns the signature indicated by <code>signature_index</code>.
+ * Returns the generic signature indicated by <code>signature_index</code>.
*
* @see #toClassSignature(String)
* @see #toMethodSignature(String)
+ * @see #toFieldSignature(String)
*/
public String getSignature() {
return getConstPool().getUtf8Info(ByteArray.readU16bit(get(), 0));
}
/**
- * Sets <code>signature_index</code> to the index of the given signature,
+ * Sets <code>signature_index</code> to the index of the given generic signature,
* which is added to a constant pool.
*
* @param sig new signature.
@@ -177,10 +178,27 @@ public class SignatureAttribute extends AttributeInfo {
TypeParameter[] params;
ClassType superClass;
ClassType[] interfaces;
- ClassSignature(TypeParameter[] p, ClassType s, ClassType[] i) {
- params = p;
- superClass = s;
- interfaces = i;
+
+ /**
+ * Constructs a class signature.
+ *
+ * @param p type parameters.
+ * @param s the super class.
+ * @param i the interface types.
+ */
+ public ClassSignature(TypeParameter[] p, ClassType s, ClassType[] i) {
+ params = p == null ? new TypeParameter[0] : p;
+ superClass = s == null ? ClassType.OBJECT : s;
+ interfaces = i == null ? new ClassType[0] : i;
+ }
+
+ /**
+ * Constructs a class signature.
+ *
+ * @param p type parameters.
+ */
+ public ClassSignature(TypeParameter[] p) {
+ this(p, null, null);
}
/**
@@ -219,6 +237,26 @@ public class SignatureAttribute extends AttributeInfo {
return sbuf.toString();
}
+
+ /**
+ * Returns the encoded string representing the method type signature.
+ */
+ public String encode() {
+ StringBuffer sbuf = new StringBuffer();
+ if (params.length > 0) {
+ sbuf.append('<');
+ for (int i = 0; i < params.length; i++)
+ params[i].encode(sbuf);
+
+ sbuf.append('>');
+ }
+
+ superClass.encode(sbuf);
+ for (int i = 0; i < interfaces.length; i++)
+ interfaces[i].encode(sbuf);
+
+ return sbuf.toString();
+ }
}
/**
@@ -230,11 +268,20 @@ public class SignatureAttribute extends AttributeInfo {
Type retType;
ObjectType[] exceptions;
- MethodSignature(TypeParameter[] tp, Type[] p, Type ret, ObjectType[] ex) {
- typeParams = tp;
- params = p;
- retType = ret;
- exceptions = ex;
+ /**
+ * Constructs a method type signature. Any parameter can be null
+ * to represent <code>void</code> or nothing.
+ *
+ * @param tp type parameters.
+ * @param p parameter types.
+ * @param ret a return type.
+ * @param ex exception types.
+ */
+ public MethodSignature(TypeParameter[] tp, Type[] p, Type ret, ObjectType[] ex) {
+ typeParams = tp == null ? new TypeParameter[0] : tp;
+ params = p == null ? new Type[0] : p;
+ retType = ret == null ? new BaseType("void") : ret;
+ exceptions = ex == null ? new ObjectType[0] : ex;
}
/**
@@ -282,10 +329,40 @@ public class SignatureAttribute extends AttributeInfo {
return sbuf.toString();
}
+
+ /**
+ * Returns the encoded string representing the method type signature.
+ */
+ public String encode() {
+ StringBuffer sbuf = new StringBuffer();
+ if (typeParams.length > 0) {
+ sbuf.append('<');
+ for (int i = 0; i < typeParams.length; i++)
+ typeParams[i].encode(sbuf);
+
+ sbuf.append('>');
+ }
+
+ sbuf.append('(');
+ for (int i = 0; i < params.length; i++)
+ params[i].encode(sbuf);
+
+ sbuf.append(')');
+ retType.encode(sbuf);
+ if (exceptions.length > 0)
+ for (int i = 0; i < exceptions.length; i++) {
+ sbuf.append('^');
+ exceptions[i].encode(sbuf);
+ }
+
+ return sbuf.toString();
+ }
}
/**
* Formal type parameters.
+ *
+ * @see TypeArgument
*/
public static class TypeParameter {
String name;
@@ -299,6 +376,33 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
+ * Constructs a <code>TypeParameter</code> representing a type parametre
+ * like <code>&lt;T extends ... &gt;<code>.
+ *
+ * @param name parameter name.
+ * @param superClass an upper bound class-type (or null).
+ * @param superInterfaces an upper bound interface-type (or null).
+ */
+ public TypeParameter(String name, ObjectType superClass, ObjectType[] superInterfaces) {
+ this.name = name;
+ this.superClass = superClass;
+ if (superInterfaces == null)
+ this.superInterfaces = new ObjectType[0];
+ else
+ this.superInterfaces = superInterfaces;
+ }
+
+ /**
+ * Constructs a <code>TypeParameter</code> representing a type parameter
+ * like <code>&lt;T&gt;<code>.
+ *
+ * @param name parameter name.
+ */
+ public TypeParameter(String name) {
+ this(name, null, null);
+ }
+
+ /**
* Returns the name of the type parameter.
*/
public String getName() {
@@ -307,8 +411,6 @@ public class SignatureAttribute extends AttributeInfo {
/**
* Returns the class bound of this parameter.
- *
- * @return null if the class bound is not specified.
*/
public ObjectType getClassBound() { return superClass; }
@@ -353,10 +455,27 @@ public class SignatureAttribute extends AttributeInfo {
sbuf.append('>');
}
+
+ void encode(StringBuffer sb) {
+ sb.append(name);
+ if (superClass == null)
+ sb.append(":Ljava/lang/Object;");
+ else {
+ sb.append(':');
+ superClass.encode(sb);
+ }
+
+ for (int i = 0; i < superInterfaces.length; i++) {
+ sb.append(':');
+ superInterfaces[i].encode(sb);
+ }
+ }
}
/**
* Type argument.
+ *
+ * @see TypeParameter
*/
public static class TypeArgument {
ObjectType arg;
@@ -368,6 +487,44 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
+ * Constructs a <code>TypeArgument</code>.
+ * A type argument is <code>&lt;String&gt;</code>, <code>&lt;int[]&gt;</code>,
+ * or a type variable <code>&lt;T&gt;</code>, etc.
+ *
+ * @param t a class type, an array type, or a type variable.
+ */
+ public TypeArgument(ObjectType t) {
+ this(t, ' ');
+ }
+
+ /**
+ * Constructs a <code>TypeArgument</code> representing <code>&lt;?&gt;</code>.
+ */
+ public TypeArgument() {
+ this(null, '*');
+ }
+
+ /**
+ * A factory method constructing a <code>TypeArgument</code> with an upper bound.
+ * It represents <code>&lt;? extends ... &gt;</code>
+ *
+ * @param t an upper bound type.
+ */
+ public static TypeArgument subclassOf(ObjectType t) {
+ return new TypeArgument(t, '+');
+ }
+
+ /**
+ * A factory method constructing a <code>TypeArgument</code> with an lower bound.
+ * It represents <code>&lt;? super ... &gt;</code>
+ *
+ * @param t an lower bbound type.
+ */
+ public static TypeArgument superOf(ObjectType t) {
+ return new TypeArgument(t, '-');
+ }
+
+ /**
* Returns the kind of this type argument.
*
* @return <code>' '</code> (not-wildcard), <code>'*'</code> (wildcard), <code>'+'</code> (wildcard with
@@ -405,12 +562,27 @@ public class SignatureAttribute extends AttributeInfo {
else
return "? super " + type;
}
+
+ static void encode(StringBuffer sb, TypeArgument[] args) {
+ sb.append('<');
+ for (int i = 0; i < args.length; i++) {
+ TypeArgument ta = args[i];
+ if (ta.isWildcard())
+ sb.append(ta.wildcard);
+
+ if (ta.getType() != null)
+ ta.getType().encode(sb);
+ }
+
+ sb.append('>');
+ }
}
/**
* Primitive types and object types.
*/
public static abstract class Type {
+ abstract void encode(StringBuffer sb);
static void toString(StringBuffer sbuf, Type[] ts) {
for (int i = 0; i < ts.length; i++) {
if (i > 0)
@@ -429,6 +601,15 @@ public class SignatureAttribute extends AttributeInfo {
BaseType(char c) { descriptor = c; }
/**
+ * Constructs a <code>BaseType</code>.
+ *
+ * @param typeName <code>void</code>, <code>int</code>, ...
+ */
+ public BaseType(String typeName) {
+ this(Descriptor.of(typeName).charAt(0));
+ }
+
+ /**
* Returns the descriptor representing this primitive type.
*
* @see javassist.bytecode.Descriptor
@@ -449,12 +630,26 @@ public class SignatureAttribute extends AttributeInfo {
public String toString() {
return Descriptor.toClassName(Character.toString(descriptor));
}
+
+ void encode(StringBuffer sb) {
+ sb.append(descriptor);
+ }
}
/**
* Class types, array types, and type variables.
+ * This class is also used for representing a field type.
*/
- public static abstract class ObjectType extends Type {}
+ public static abstract class ObjectType extends Type {
+ /**
+ * Returns the encoded string representing the object type signature.
+ */
+ public String encode() {
+ StringBuffer sb = new StringBuffer();
+ encode(sb);
+ return sb.toString();
+ }
+ }
/**
* Class types.
@@ -477,6 +672,23 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
+ * A class type representing <code>java.lang.Object</code>.
+ */
+ public static ClassType OBJECT = new ClassType("java.lang.Object", null);
+
+ /**
+ * Constructs a <code>ClassType</code>. It represents
+ * the name of a non-nested class.
+ *
+ * @param className a fully qualified class name.
+ * @param args type arguments or null.
+ */
+ public ClassType(String className, TypeArgument[] args) {
+ name = className;
+ arguments = args;
+ }
+
+ /**
* Returns the class name.
*/
public String getName() {
@@ -523,6 +735,24 @@ public class SignatureAttribute extends AttributeInfo {
return sbuf.toString();
}
+
+ void encode(StringBuffer sb) {
+ sb.append('L');
+ encode2(sb);
+ sb.append(';');
+ }
+
+ void encode2(StringBuffer sb) {
+ ClassType parent = getDeclaringClass();
+ if (parent != null) {
+ parent.encode2(sb);
+ sb.append('$');
+ }
+
+ sb.append(name.replace('.', '/'));
+ if (arguments != null)
+ TypeArgument.encode(sb, arguments);
+ }
}
/**
@@ -537,6 +767,19 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
+ * Constructs a <code>NestedClassType</code>.
+ *
+ * @param parent the class surrounding this class type.
+ * @param className a simple class name. It does not include
+ * a package name or a parent's class name.
+ * @param args type parameters or null.
+ */
+ public NestedClassType(ClassType parent, String className, TypeArgument[] args) {
+ super(className, args);
+ this.parent = parent;
+ }
+
+ /**
* Returns the class that declares this nested class.
* This nested class is a member of that declaring class.
*/
@@ -550,6 +793,12 @@ public class SignatureAttribute extends AttributeInfo {
int dim;
Type componentType;
+ /**
+ * Constructs an <code>ArrayType</code>.
+ *
+ * @param d dimension.
+ * @param comp the component type.
+ */
public ArrayType(int d, Type comp) {
dim = d;
componentType = comp;
@@ -577,6 +826,13 @@ public class SignatureAttribute extends AttributeInfo {
return sbuf.toString();
}
+
+ void encode(StringBuffer sb) {
+ for (int i = 0; i < dim; i++)
+ sb.append('[');
+
+ componentType.encode(sb);
+ }
}
/**
@@ -590,6 +846,15 @@ public class SignatureAttribute extends AttributeInfo {
}
/**
+ * Constructs a <code>TypeVariable</code>.
+ *
+ * @param name the name of a type variable.
+ */
+ public TypeVariable(String name) {
+ this.name = name;
+ }
+
+ /**
* Returns the variable name.
*/
public String getName() {
@@ -602,13 +867,21 @@ public class SignatureAttribute extends AttributeInfo {
public String toString() {
return name;
}
+
+ void encode(StringBuffer sb) {
+ sb.append('T').append(name).append(';');
+ }
}
/**
* Parses the given signature string as a class signature.
*
- * @param sig the signature.
+ * @param sig the signature obtained from the <code>SignatureAttribute</code>
+ * of a <code>ClassFile</code>.
+ * @return a tree-like data structure representing a class signature. It provides
+ * convenient accessor methods.
* @throws BadBytecode thrown when a syntactical error is found.
+ * @see #getSignature()
* @since 3.5
*/
public static ClassSignature toClassSignature(String sig) throws BadBytecode {
@@ -623,8 +896,12 @@ public class SignatureAttribute extends AttributeInfo {
/**
* Parses the given signature string as a method type signature.
*
- * @param sig the signature.
+ * @param sig the signature obtained from the <code>SignatureAttribute</code>
+ * of a <code>MethodInfo</code>.
+ * @return @return a tree-like data structure representing a method signature. It provides
+ * convenient accessor methods.
* @throws BadBytecode thrown when a syntactical error is found.
+ * @see #getSignature()
* @since 3.5
*/
public static MethodSignature toMethodSignature(String sig) throws BadBytecode {
@@ -639,9 +916,11 @@ public class SignatureAttribute extends AttributeInfo {
/**
* Parses the given signature string as a field type signature.
*
- * @param sig the signature string.
+ * @param sig the signature string obtained from the <code>SignatureAttribute</code>
+ * of a <code>FieldInfo</code>.
* @return the field type signature.
* @throws BadBytecode thrown when a syntactical error is found.
+ * @see #getSignature()
* @since 3.5
*/
public static ObjectType toFieldSignature(String sig) throws BadBytecode {