summaryrefslogtreecommitdiff
path: root/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java')
-rw-r--r--asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java33
1 files changed, 20 insertions, 13 deletions
diff --git a/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java b/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
index 2217a88a..df5f61d0 100644
--- a/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
+++ b/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
@@ -41,7 +41,7 @@ import org.objectweb.asm.Opcodes;
public class SignatureWriter extends SignatureVisitor {
/** The builder used to construct the visited signature. */
- private final StringBuilder stringBuilder = new StringBuilder();
+ private final StringBuilder stringBuilder;
/** Whether the visited signature contains formal type parameters. */
private boolean hasFormals;
@@ -51,8 +51,9 @@ public class SignatureWriter extends SignatureVisitor {
/**
* The stack used to keep track of class types that have arguments. Each element of this stack is
- * a boolean encoded in one bit. The top of the stack is the least significant bit. Pushing false
- * = *2, pushing true = *2+1, popping = /2.
+ * a boolean encoded in one bit. The top of the stack is the least significant bit. The bottom of
+ * the stack is a sentinel element always equal to 1 (used to detect when the stack is full).
+ * Pushing false = {@code <<= 1}, pushing true = {@code '( <<= 1) | 1}, popping = {@code >>>= 1}.
*
* <p>Class type arguments must be surrounded with '&lt;' and '&gt;' and, because
*
@@ -62,15 +63,20 @@ public class SignatureWriter extends SignatureVisitor {
* SignatureWriter instances),
* </ol>
*
- * <p>we need a stack to properly balance these 'parentheses'. A new element is pushed on this
- * stack for each new visited type, and popped when the visit of this type ends (either is
+ * <p>we need a stack to properly balance these angle brackets. A new element is pushed on this
+ * stack for each new visited type, and popped when the visit of this type ends (either in
* visitEnd, or because visitInnerClassType is called).
*/
- private int argumentStack;
+ private int argumentStack = 1;
/** Constructs a new {@link SignatureWriter}. */
public SignatureWriter() {
+ this(new StringBuilder());
+ }
+
+ private SignatureWriter(final StringBuilder stringBuilder) {
super(/* latest api =*/ Opcodes.ASM9);
+ this.stringBuilder = stringBuilder;
}
// -----------------------------------------------------------------------------------------------
@@ -159,7 +165,7 @@ public class SignatureWriter extends SignatureVisitor {
stringBuilder.append(name);
// Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as
// we can tell at this point).
- argumentStack *= 2;
+ argumentStack <<= 1;
}
@Override
@@ -169,7 +175,7 @@ public class SignatureWriter extends SignatureVisitor {
stringBuilder.append(name);
// Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as
// we can tell at this point).
- argumentStack *= 2;
+ argumentStack <<= 1;
}
@Override
@@ -177,7 +183,7 @@ public class SignatureWriter extends SignatureVisitor {
// If the top of the stack is 'false', this means we are visiting the first type argument of the
// currently visited type. We therefore need to append a '<', and to replace the top stack
// element with 'true' (meaning that the current type does have type arguments).
- if (argumentStack % 2 == 0) {
+ if ((argumentStack & 1) == 0) {
argumentStack |= 1;
stringBuilder.append('<');
}
@@ -189,14 +195,15 @@ public class SignatureWriter extends SignatureVisitor {
// If the top of the stack is 'false', this means we are visiting the first type argument of the
// currently visited type. We therefore need to append a '<', and to replace the top stack
// element with 'true' (meaning that the current type does have type arguments).
- if (argumentStack % 2 == 0) {
+ if ((argumentStack & 1) == 0) {
argumentStack |= 1;
stringBuilder.append('<');
}
if (wildcard != '=') {
stringBuilder.append(wildcard);
}
- return this;
+ // If the stack is full, start a nested one by returning a new SignatureWriter.
+ return (argumentStack & (1 << 31)) == 0 ? this : new SignatureWriter(stringBuilder);
}
@Override
@@ -232,9 +239,9 @@ public class SignatureWriter extends SignatureVisitor {
// If the top of the stack is 'true', this means that some type arguments have been visited for
// the type whose visit is now ending. We therefore need to append a '>', and to pop one element
// from the stack.
- if (argumentStack % 2 == 1) {
+ if ((argumentStack & 1) == 1) {
stringBuilder.append('>');
}
- argumentStack /= 2;
+ argumentStack >>>= 1;
}
}