From: <lk...@us...> - 2006-03-29 12:21:46
|
Update of /cvsroot/clirr/clirr/core/src/java/net/sf/clirr/core/internal/asm In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19663/src/java/net/sf/clirr/core/internal/asm Modified Files: AsmMethod.java AsmJavaType.java Repository.java Added Files: ArrayType.java Log Message: Fixed regression #1459639, array dimension change no longer detected. While I was working on that bug, I noticed a few other glitches that were introduced when switching from BCEL to ASM, some of them are fixed in this commit as well. --- NEW FILE --- package net.sf.clirr.core.internal.asm; import net.sf.clirr.core.spi.Field; import net.sf.clirr.core.spi.JavaType; import net.sf.clirr.core.spi.Method; import net.sf.clirr.core.spi.Scope; class ArrayType implements JavaType { private final JavaType basicType; private final int dimension; ArrayType(JavaType basicType, int dimension) { this.basicType = basicType; this.dimension = dimension; } public String getBasicName() { return basicType.getBasicName(); } public String getName() { StringBuffer arrayDimIndicator = new StringBuffer(); final int arrayDimension = getArrayDimension(); for (int i = 0; i < arrayDimension; i++) { arrayDimIndicator.append("[]"); } return basicType.getBasicName() + arrayDimIndicator; } public JavaType getContainingClass() { // TODO Auto-generated method stub return null; } public JavaType[] getSuperClasses() { // TODO Auto-generated method stub return null; } public JavaType[] getAllInterfaces() { // TODO Auto-generated method stub return null; } public JavaType[] getInnerClasses() { // TODO Auto-generated method stub return null; } public Method[] getMethods() { // TODO Auto-generated method stub return null; } public Field[] getFields() { return new Field[0]; } public int getArrayDimension() { return dimension; } public boolean isPrimitive() { return basicType.isPrimitive(); } public boolean isFinal() { return false; } public boolean isAbstract() { return false; } public boolean isInterface() { // TODO Auto-generated method stub return false; } public Scope getDeclaredScope() { return basicType.getDeclaredScope(); } public Scope getEffectiveScope() { return basicType.getEffectiveScope(); } public String toString() { return "ArrayType[" + basicType.toString() + " ^ " + dimension + "]"; } } Index: AsmMethod.java =================================================================== RCS file: /cvsroot/clirr/clirr/core/src/java/net/sf/clirr/core/internal/asm/AsmMethod.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- AsmMethod.java 28 Mar 2006 19:25:55 -0000 1.2 +++ AsmMethod.java 29 Mar 2006 12:21:41 -0000 1.3 @@ -7,7 +7,7 @@ import net.sf.clirr.core.spi.Method; import net.sf.clirr.core.spi.Scope; -public class AsmMethod extends AbstractAsmScoped implements Method +class AsmMethod extends AbstractAsmScoped implements Method { private final Repository repository; @@ -36,12 +36,12 @@ { return null; } - return findJavaType(returnType); + final JavaType javaType = findJavaType(returnType); + return javaType; } public JavaType[] getArgumentTypes() { - // TODO support primitive types JavaType[] ret = new JavaType[argumentTypes.length]; for (int i = 0; i < ret.length; i++) { Index: AsmJavaType.java =================================================================== RCS file: /cvsroot/clirr/clirr/core/src/java/net/sf/clirr/core/internal/asm/AsmJavaType.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AsmJavaType.java 16 Mar 2006 22:30:19 -0000 1.1 +++ AsmJavaType.java 29 Mar 2006 12:21:41 -0000 1.2 @@ -1,7 +1,10 @@ package net.sf.clirr.core.internal.asm; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.objectweb.asm.Opcodes; @@ -10,11 +13,11 @@ import net.sf.clirr.core.spi.Method; import net.sf.clirr.core.spi.Scope; -public class AsmJavaType extends AbstractAsmScoped implements JavaType +class AsmJavaType extends AbstractAsmScoped implements JavaType { private final Repository repository; - private final String name; + private final String basicName; private String superClassName; @@ -24,11 +27,11 @@ private final String[] interfaceNames; - public AsmJavaType(Repository repository, int access, String name, String superClassName, String[] interfaceNames) + public AsmJavaType(Repository repository, int access, String basicName, String superClassName, String[] interfaceNames) { super(access); this.repository = repository; - this.name = name; + this.basicName = basicName; this.superClassName = superClassName; this.interfaceNames = interfaceNames; } @@ -36,13 +39,13 @@ public String getBasicName() { - // TODO handle array types correctly - return name; + return basicName; } public String getName() { - return name; + // arrays are always represented by ArrayType instances, so name == basicName + return basicName; } public JavaType getContainingClass() @@ -67,11 +70,21 @@ public JavaType[] getAllInterfaces() { - JavaType[] ret = new JavaType[interfaceNames.length]; - for (int i = 0; i < ret.length; i++) + Set interfaceSet = new HashSet(interfaceNames.length); + for (int i = 0; i < interfaceNames.length; i++) { - ret[i] = repository.findTypeByName(interfaceNames[i]); + JavaType type = repository.findTypeByName(interfaceNames[i]); + interfaceSet.add(type); } + JavaType[] superClasses = getSuperClasses(); + for (int i = 0; i < superClasses.length; i++) + { + JavaType superClass = superClasses[i]; + final JavaType[] superInterfaces = superClass.getAllInterfaces(); + interfaceSet.addAll(Arrays.asList(superInterfaces)); + } + final JavaType[] ret = new JavaType[interfaceSet.size()]; + interfaceSet.toArray(ret); return ret; } @@ -138,8 +151,36 @@ return getDeclaredScope(); } + public String toString() { - return "AsmJavaType[" + name + "]"; + return "AsmJavaType[" + getName() + "]"; } + + + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + if (!AsmJavaType.class.equals(obj.getClass())) + { + return false; + } + AsmJavaType other = (AsmJavaType) obj; + if (other.repository != this.repository) + { + return false; + } + return (other.getName().equals(this.getName())); + } + + + public int hashCode() + { + return getName().hashCode(); + } + + } Index: Repository.java =================================================================== RCS file: /cvsroot/clirr/clirr/core/src/java/net/sf/clirr/core/internal/asm/Repository.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Repository.java 16 Mar 2006 22:30:19 -0000 1.1 +++ Repository.java 29 Mar 2006 12:21:41 -0000 1.2 @@ -23,17 +23,16 @@ */ class Repository { - private static final Pattern PRIMITIVE_PATTERN = Pattern.compile("(int|float|long|double|boolean|char|short)(\\[\\])*"); + private static final Pattern PRIMITIVE_PATTERN = Pattern.compile("(int|float|long|double|boolean|char|short|byte)"); + private static final Pattern ARRAY_PATTERN = Pattern.compile("(\\[\\])+$"); private static final class PrimitiveType implements JavaType { private final String basicName; - private final int dimension; - private PrimitiveType(String name, int dimension) + private PrimitiveType(String name) { this.basicName = name; - this.dimension = dimension; } public String getBasicName() @@ -43,11 +42,6 @@ public String getName() { - String name = basicName; - for (int i = 0; i < getArrayDimension(); i++) - { - name += "[]"; - } return basicName; } @@ -83,7 +77,7 @@ public int getArrayDimension() { - return dimension; + return 0; } public boolean isPrimitive() @@ -150,42 +144,49 @@ return javaType; } - public JavaType findTypeByName(String typeName) + public JavaType findTypeByName(String fullTypeName) { + // separate basic typename and array brackets + final Matcher arrayMatcher = ARRAY_PATTERN.matcher(fullTypeName); + final String typeName; + final int dimension; + if (arrayMatcher.find()) + { + String brackets = arrayMatcher.group(); + typeName = fullTypeName.substring(0, fullTypeName.length() - brackets.length()); + dimension = brackets.length() / 2; + } + else + { + typeName = fullTypeName; + dimension = 0; + } + + // search cache for basic typename JavaType type = (JavaType) nameTypeMap.get(typeName); if (type != null) { - return type; + return wrapInArrayTypeIfRequired(dimension, type); } - final Matcher matcher = PRIMITIVE_PATTERN.matcher(typeName); - if (matcher.matches()) + + final Matcher primitiveMatcher = PRIMITIVE_PATTERN.matcher(typeName); + if (primitiveMatcher.matches()) { - final String basicType = matcher.group(1); - final String arrayBrackets = matcher.group(2); - final int dimension = arrayBrackets == null ? 0 : arrayBrackets.length() / 2; - JavaType primitive = new PrimitiveType(basicType, dimension); + JavaType primitive = new PrimitiveType(typeName); nameTypeMap.put(typeName, primitive); - return primitive; + return wrapInArrayTypeIfRequired(dimension, primitive); } + String resourceName = typeName.replace('.', '/') + ".class"; InputStream is = classLoader.getResourceAsStream(resourceName); if (is == null) { - String clDetails; - if (classLoader instanceof URLClassLoader) - { - URLClassLoader ucl = (URLClassLoader) classLoader; - clDetails = String.valueOf(Arrays.asList(ucl.getURLs())); - } - else - { - clDetails = String.valueOf(classLoader); - } - throw new IllegalArgumentException("Type " + typeName + " is unknown in classLoader " + clDetails); + reportTypeUnknownInClassLoader(typeName); } try { - return readJavaTypeFromStream(is); + final AsmJavaType javaType = readJavaTypeFromStream(is); + return wrapInArrayTypeIfRequired(dimension, javaType); } catch (IOException ex) { @@ -203,4 +204,37 @@ } } + /** + * @param dimension + * @param javaType + * @return + */ + private JavaType wrapInArrayTypeIfRequired(final int dimension, final JavaType javaType) + { + if (dimension == 0) + { + return javaType; + } + final ArrayType arrayType = new ArrayType(javaType, dimension); + return arrayType; + } + + /** + * @param typeName + */ + private void reportTypeUnknownInClassLoader(final String typeName) + { + String clDetails; + if (classLoader instanceof URLClassLoader) + { + URLClassLoader ucl = (URLClassLoader) classLoader; + clDetails = String.valueOf(Arrays.asList(ucl.getURLs())); + } + else + { + clDetails = String.valueOf(classLoader); + } + throw new IllegalArgumentException("Type " + typeName + " is unknown in classLoader " + clDetails); + } + } |