aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/src/org/aspectj/util/GenericSignatureParser.java56
-rw-r--r--util/testsrc/org/aspectj/util/GenericSignatureParserTest.java23
2 files changed, 58 insertions, 21 deletions
diff --git a/util/src/org/aspectj/util/GenericSignatureParser.java b/util/src/org/aspectj/util/GenericSignatureParser.java
index 3f11662f6..28c8db83d 100644
--- a/util/src/org/aspectj/util/GenericSignatureParser.java
+++ b/util/src/org/aspectj/util/GenericSignatureParser.java
@@ -187,18 +187,10 @@ public class GenericSignatureParser {
// now we have either a "." indicating the start of a nested type,
// or a "<" indication type arguments, or ";" and we are done.
while (!maybeEat(";")) {
- if (maybeEat(".")) {
+ if (tokenStream[tokenIndex].equals(".")) {
// outer type completed
outerType = new SimpleClassTypeSignature(identifier);
- List<SimpleClassTypeSignature> nestedTypeList = new ArrayList<SimpleClassTypeSignature>();
- do {
- ret.append(".");
- SimpleClassTypeSignature sig = parseSimpleClassTypeSignature();
- ret.append(sig.toString());
- nestedTypeList.add(sig);
- } while (maybeEat("."));
- nestedTypes = new SimpleClassTypeSignature[nestedTypeList.size()];
- nestedTypeList.toArray(nestedTypes);
+ nestedTypes = parseNestedTypesHelper(ret);
} else if (tokenStream[tokenIndex].equals("<")) {
ret.append("<");
TypeArgument[] tArgs = maybeParseTypeArguments();
@@ -207,16 +199,7 @@ public class GenericSignatureParser {
}
ret.append(">");
outerType = new SimpleClassTypeSignature(identifier, tArgs);
- // now parse possible nesteds...
- List<SimpleClassTypeSignature> nestedTypeList = new ArrayList<SimpleClassTypeSignature>();
- while (maybeEat(".")) {
- ret.append(".");
- SimpleClassTypeSignature sig = parseSimpleClassTypeSignature();
- ret.append(sig.toString());
- nestedTypeList.add(sig);
- }
- nestedTypes = new SimpleClassTypeSignature[nestedTypeList.size()];
- nestedTypeList.toArray(nestedTypes);
+ nestedTypes = parseNestedTypesHelper(ret);
} else {
throw new IllegalStateException("Expecting .,<, or ;, but found " + tokenStream[tokenIndex] + " while unpacking "
+ inputString);
@@ -228,6 +211,39 @@ public class GenericSignatureParser {
return new ClassTypeSignature(ret.toString(), outerType, nestedTypes);
}
+ /**
+ * Helper method to digest nested types, slightly more complex than necessary to cope with some android related
+ * incorrect classes (see bug 406167)
+ */
+ private SimpleClassTypeSignature[] parseNestedTypesHelper(StringBuffer ret) {
+ boolean brokenSignature = false;
+ SimpleClassTypeSignature[] nestedTypes;
+ List<SimpleClassTypeSignature> nestedTypeList = new ArrayList<SimpleClassTypeSignature>();
+ while (maybeEat(".")) {
+ ret.append(".");
+ SimpleClassTypeSignature sig = parseSimpleClassTypeSignature();
+ if (tokenStream[tokenIndex].equals("/")) {
+ if (!brokenSignature) {
+ System.err.println("[See bug 406167] Bad class file signature encountered, nested types appear package qualified, ignoring those incorrect pieces. Signature: "+inputString);
+ }
+ brokenSignature = true;
+ // hit something like: Lcom/a/a/b/t<TK;TV;>.com/a/a/b/af.com/a/a/b/ag;
+ // and we are looking at the '/' after the com
+ tokenIndex++; // pointing at the next identifier
+ while (tokenStream[tokenIndex+1].equals("/")) {
+ tokenIndex+=2; // jump over an 'identifier' '/' pair
+ }
+ // now tokenIndex is the final bit of the name (which we'll treat as the inner type name)
+ sig = parseSimpleClassTypeSignature();
+ }
+ ret.append(sig.toString());
+ nestedTypeList.add(sig);
+ };
+ nestedTypes = new SimpleClassTypeSignature[nestedTypeList.size()];
+ nestedTypeList.toArray(nestedTypes);
+ return nestedTypes;
+ }
+
private SimpleClassTypeSignature parseSimpleClassTypeSignature() {
String identifier = eatIdentifier();
TypeArgument[] tArgs = maybeParseTypeArguments();
diff --git a/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java b/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java
index c46c97b63..5a9e083e4 100644
--- a/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java
+++ b/util/testsrc/org/aspectj/util/GenericSignatureParserTest.java
@@ -95,6 +95,27 @@ public class GenericSignatureParserTest extends TestCase {
assertEquals("Ljava/util/Comparable<-TE;>;", sig.superInterfaceSignatures[0].toString());
}
+ public void testFunky_406167() {
+ ClassSignature sig = parser
+ .parseAsClassSignature("Lcom/google/android/gms/internal/hb<TT;>.com/google/android/gms/internal/hb$b<Ljava/lang/Boolean;>;");
+ // Note the package prefix on the nested types has been dropped
+ assertEquals("Lcom/google/android/gms/internal/hb<TT;>.hb$b<Ljava/lang/Boolean;>;",sig.superclassSignature.toString());
+ sig = parser
+ .parseAsClassSignature("Lcom/a/a/b/t<TK;TV;>.com/a/a/b/af.com/a/a/b/ag;Ljava/util/ListIterator<TV;>;");
+ // Note the package prefix on the nested types has been dropped
+ assertEquals("Lcom/a/a/b/t<TK;TV;>.af.ag;",sig.superclassSignature.toString());
+ assertEquals("Ljava/util/ListIterator<TV;>;",sig.superInterfaceSignatures[0].toString());
+ sig = parser.parseAsClassSignature("Lcom/google/android/gms/internal/hb.com/google/android/gms/internal/hb$b<Ljava/lang/Boolean;>;");
+ // Note the package prefix on the nested types has been dropped
+ assertEquals("Lcom/google/android/gms/internal/hb.hb$b<Ljava/lang/Boolean;>;",sig.superclassSignature.toString());
+ sig = parser
+ .parseAsClassSignature("Lcom/a/a/b/t.com/a/a/b/af.com/a/a/b/ag;Ljava/util/ListIterator<TV;>;");
+ // Note the package prefix on the nested types has been dropped
+ assertEquals("Lcom/a/a/b/t.af.ag;",sig.superclassSignature.toString());
+ assertEquals("Ljava/util/ListIterator<TV;>;",sig.superInterfaceSignatures[0].toString());
+ }
+
+
public void testFieldSignatureParsingClassType() {
FieldTypeSignature fsig = parser.parseAsFieldSignature("Ljava/lang/String;");
assertTrue("ClassTypeSignature", fsig instanceof ClassTypeSignature);
@@ -155,7 +176,7 @@ public class GenericSignatureParserTest extends TestCase {
assertEquals("Ljava/lang/Exception;", mSig.throwsSignatures[0].toString());
assertEquals("Ljava/lang/RuntimeException;", mSig.throwsSignatures[1].toString());
}
-
+
public void testMethodSignaturePrimitiveParams() {
GenericSignature.MethodTypeSignature mSig = parser.parseAsMethodSignature("(ILjava/lang/Object;)V");
assertEquals("2 parameters", 2, mSig.parameters.length);