Author: ebourg Date: Thu Feb 19 09:55:24 2015 New Revision: 1660822 URL: http://svn.apache.org/r1660822 Log: Add support for TypeVariables to Utility.signatureToString(). Thanks to Mark Roberts (BCEL-197)
Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java (with props) Modified: commons/proper/bcel/trunk/RELEASE-NOTES.txt commons/proper/bcel/trunk/src/changes/changes.xml commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java Modified: commons/proper/bcel/trunk/RELEASE-NOTES.txt URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/RELEASE-NOTES.txt?rev=1660822&r1=1660821&r2=1660822&view=diff ============================================================================== --- commons/proper/bcel/trunk/RELEASE-NOTES.txt (original) +++ commons/proper/bcel/trunk/RELEASE-NOTES.txt Thu Feb 19 09:55:24 2015 @@ -97,6 +97,7 @@ Bug fixes from 5.2 [BCEL-177] MethodParameters should read 1 byte not two for parameter count [BCEL-181] ClassLoaderRepository.loadClass(String) leaks input streams [BCEL-194] LocalVariableGen hashCode() function is incorrrect +[BCEL-197] Add support for TypeVariables to Utility.signatureToString() Feedback Modified: commons/proper/bcel/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/changes/changes.xml?rev=1660822&r1=1660821&r2=1660822&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/changes/changes.xml (original) +++ commons/proper/bcel/trunk/src/changes/changes.xml Thu Feb 19 09:55:24 2015 @@ -63,6 +63,10 @@ The <action> type attribute can be add,u <body> <release version="6.0" date="TBA" description="Major release with Java 7 and 8 support"> + <action issue="BCEL-197" type="fix" due-to="Mark Roberts"> + Utility.signatureToString() no longer throws a ClassFormatException on TypeVariables + found in generic signatures. + </action> <action issue="BCEL-194" type="fix" due-to="Mark Roberts"> Removed the 'index' variable from the LocalVariableGen's hash code. </action> Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java?rev=1660822&r1=1660821&r2=1660822&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java Thu Feb 19 09:55:24 2015 @@ -823,15 +823,72 @@ public abstract class Utility { return "int"; case 'J': return "long"; - case 'L': { // Full class name + case 'T': { // TypeVariableSignature int index = signature.indexOf(';'); // Look for closing `;' if (index < 0) { throw new ClassFormatException("Invalid signature: " + signature); } //corrected concurrent private static field acess - wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed + wrap(consumed_chars, index + 1); // "Tblabla;" `T' and `;' are removed return compactClassName(signature.substring(1, index), chopit); } + case 'L': { // Full class name + int index = signature.indexOf(';'); // Look for closing `;' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + // check to see if there are any TypeArguments + int bracketIndex = signature.substring(0, index).indexOf('<'); + if (bracketIndex < 0) { + // just a class identifier + wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed + return compactClassName(signature.substring(1, index), chopit); + } + + // we have TypeArguments; build up partial result + // as we recurse for each TypeArgument + String type = compactClassName(signature.substring(1, bracketIndex), chopit) + "<"; + int consumed_chars = bracketIndex + 1; // Shadows global var + + // check for wildcards + if (signature.charAt(consumed_chars) == '+') { + type = type + "? extends "; + consumed_chars = ++consumed_chars; + } else if (signature.charAt(consumed_chars) == '-') { + type = type + "? super "; + consumed_chars = ++consumed_chars; + } else if (signature.charAt(consumed_chars) == '*') { + // must be at end of signature + if (signature.charAt(consumed_chars + 1) != '>') { + throw new ClassFormatException("Invalid signature: " + signature); + } + if (signature.charAt(consumed_chars + 2) != ';') { + throw new ClassFormatException("Invalid signature: " + signature); + } + wrap(Utility.consumed_chars, consumed_chars + 3); // remove final "*>;" + return type + "?>..."; + } + + // get the first TypeArgument + type = type + signatureToString(signature.substring(consumed_chars), chopit); + // update our consumed count by the number of characters the for type argument + consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars; + wrap(Utility.consumed_chars, consumed_chars); + + // are there more TypeArguments? + while (signature.charAt(consumed_chars) != '>') { + type = type + ", " + signatureToString(signature.substring(consumed_chars), chopit); + // update our consumed count by the number of characters the for type argument + consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars; + wrap(Utility.consumed_chars, consumed_chars); + } + + if (signature.charAt(consumed_chars + 1) != ';') { + throw new ClassFormatException("Invalid signature: " + signature); + } + wrap(Utility.consumed_chars, consumed_chars + 2); // remove final ">;" + return type + ">"; + } case 'S': return "short"; case 'Z': Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java?rev=1660822&view=auto ============================================================================== --- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java (added) +++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java Thu Feb 19 09:55:24 2015 @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.bcel.classfile; + +import junit.framework.TestCase; + +public class UtilityTestCase extends TestCase { + + public void testSignatureToStringWithGenerics() throws Exception { + assertEquals("generic signature", "java.util.Map<X, java.util.List<Y>>", Utility.signatureToString("Ljava/util/Map<TX;Ljava/util/List<TY;>;>;")); + assertEquals("generic signature", "java.util.Set<? extends java.nio.file.OpenOption>", Utility.signatureToString("Ljava/util/Set<+Ljava/nio/file/OpenOption;>;")); + assertEquals("generic signature", "java.nio.file.attribute.FileAttribute<?>...[]", Utility.signatureToString("[Ljava/nio/file/attribute/FileAttribute<*>;")); + } +} Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/classfile/UtilityTestCase.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL