diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/src/org/aspectj/util/GenericSignatureParser.java | 56 | ||||
-rw-r--r-- | util/testsrc/org/aspectj/util/GenericSignatureParserTest.java | 23 |
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); |