summaryrefslogtreecommitdiff
path: root/asm/src
diff options
context:
space:
mode:
authorEric Bruneton <ebruneton@free.fr>2022-09-11 09:09:10 +0200
committerEric Bruneton <ebruneton@free.fr>2022-09-11 09:09:10 +0200
commitedb880104a5f2b1a918b0da3ee668febe0ba45bb (patch)
tree5025016f05680f22f3f840cbafa0ac161d349d57 /asm/src
parentdac1a9fd6526a2bf985f88c59b624b5e8dbae515 (diff)
downloadow2-asm-edb880104a5f2b1a918b0da3ee668febe0ba45bb.tar.gz
Rewrite the code in a more concise way.
Diffstat (limited to 'asm/src')
-rw-r--r--asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java68
-rw-r--r--asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java48
-rw-r--r--asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java15
3 files changed, 33 insertions, 98 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 c834eef0..df5f61d0 100644
--- a/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
+++ b/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
@@ -27,8 +27,6 @@
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.signature;
-import java.util.ArrayList;
-import java.util.List;
import org.objectweb.asm.Opcodes;
/**
@@ -43,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;
@@ -53,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
- * {@code <<= 1}, pushing true {@code <<= 1; |= 1}, popping {@code >>>= 1}.
+ * 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
*
@@ -65,20 +64,19 @@ public class SignatureWriter extends SignatureVisitor {
* </ol>
*
* <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 is
+ * 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;
-
- /** The sum of the depths of {@link #argumentStack} and {@link #deepArgStack}. */
- private long argumentStackDepth;
-
- /** Used when {@link #argumentStack} can no longer fit into a single 32-bit integer. */
- private List<Integer> deepArgStack;
+ 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;
}
// -----------------------------------------------------------------------------------------------
@@ -167,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).
- pushArgStack(false);
+ argumentStack <<= 1;
}
@Override
@@ -177,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).
- pushArgStack(false);
+ argumentStack <<= 1;
}
@Override
@@ -185,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 (argumentStackDepth > 0 && !peekArgStack()) {
+ if ((argumentStack & 1) == 0) {
argumentStack |= 1;
stringBuilder.append('<');
}
@@ -197,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 (argumentStackDepth > 0 && !peekArgStack()) {
+ 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
@@ -240,40 +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 (argumentStackDepth > 0 && popArgStack()) {
+ if ((argumentStack & 1) == 1) {
stringBuilder.append('>');
}
- }
-
- private boolean peekArgStack() {
- assert argumentStackDepth > 0 : this;
- return (argumentStack & 1) == 1;
- }
-
- private void pushArgStack(final boolean state) {
- if (argumentStackDepth > 0 && (argumentStackDepth % 32) == 0) {
- if (deepArgStack == null) {
- deepArgStack = new ArrayList<>(5);
- }
- deepArgStack.add(argumentStack);
- argumentStack = 0;
- } else {
- argumentStack <<= 1;
- }
- argumentStackDepth++;
- if (state) {
- argumentStack |= 1;
- }
- }
-
- private boolean popArgStack() {
- assert argumentStackDepth > 0 : this;
- boolean result = (argumentStack & 1) == 1;
argumentStack >>>= 1;
- argumentStackDepth--;
- if (argumentStackDepth > 0 && (argumentStackDepth % 32) == 0) {
- argumentStack = deepArgStack.remove(deepArgStack.size() - 1);
- }
- return result;
}
}
diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java b/asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java
index 3717f4bd..be1ba012 100644
--- a/asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java
+++ b/asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java
@@ -29,7 +29,6 @@ package org.objectweb.asm.signature;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import java.util.stream.IntStream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.objectweb.asm.test.AsmTest;
@@ -41,10 +40,6 @@ import org.objectweb.asm.test.AsmTest;
*/
class SignatureWriterTest extends AsmTest {
- private static final String TEST_CLOSE = "TestClose";
- private static final String TEST_GENERIC = "TestGeneric";
- private static final String TEST_OPEN = "TestOpen";
-
@ParameterizedTest
@MethodSource({
"org.objectweb.asm.signature.SignaturesProviders#classSignatures",
@@ -67,47 +62,4 @@ class SignatureWriterTest extends AsmTest {
assertEquals(signature, signatureWriter.toString());
}
-
- static IntStream deepSignatures() {
- return IntStream.range(0, 48);
- }
-
- @ParameterizedTest
- @MethodSource("deepSignatures")
- void testWrite_deepSignature(final int depth) {
- SignatureWriter signatureWriter = new SignatureWriter();
- String expected = writeDeepSignature(signatureWriter, depth);
- assertEquals(expected, signatureWriter.toString(), "depth=" + depth);
- }
-
- private String writeDeepSignature(final SignatureVisitor signatureVisitor, final int maxDepth) {
- StringBuilder expected = new StringBuilder();
- writeDeepSignatureInner(signatureVisitor, expected, 0, maxDepth);
- return expected.toString();
- }
-
- private void writeDeepSignatureInner(
- final SignatureVisitor signatureVisitor,
- final StringBuilder expected,
- final int currentDepth,
- final int maxDepth) {
- signatureVisitor.visitClassType(TEST_GENERIC);
- expected.append('L' + TEST_GENERIC);
- if (currentDepth < maxDepth) {
- expected.append("<L" + TEST_OPEN + ';');
- SignatureVisitor v = signatureVisitor.visitTypeArgument('=');
- v.visitClassType(TEST_OPEN);
- v.visitEnd();
-
- writeDeepSignatureInner(
- signatureVisitor.visitTypeArgument('='), expected, currentDepth + 1, maxDepth);
-
- v = signatureVisitor.visitTypeArgument('=');
- v.visitClassType(TEST_CLOSE);
- v.visitEnd();
- expected.append('L' + TEST_CLOSE + ";>");
- }
- signatureVisitor.visitEnd();
- expected.append(';');
- }
}
diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java b/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java
index ce6cf22a..a04d5801 100644
--- a/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java
+++ b/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java
@@ -32,6 +32,9 @@ public final class SignaturesProviders {
assertFalse(CLASS_SIGNATURES.isEmpty());
assertFalse(FIELD_SIGNATURES.isEmpty());
assertFalse(METHOD_SIGNATURES.isEmpty());
+ for (int depth = 0; depth < 48; ++depth) {
+ METHOD_SIGNATURES.add(buildDeepSignature(new StringBuilder(), depth).toString());
+ }
}
private SignaturesProviders() {}
@@ -82,6 +85,18 @@ public final class SignaturesProviders {
0);
}
+ private static StringBuilder buildDeepSignature(final StringBuilder signature, final int depth) {
+ signature.append("LGeneric");
+ if (depth == 0) {
+ signature.append(';');
+ } else {
+ signature.append("<LOpen;");
+ buildDeepSignature(signature, depth - 1);
+ signature.append("LClose;>;");
+ }
+ return signature;
+ }
+
static Stream<String> classSignatures() {
return CLASS_SIGNATURES.stream();
}