diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main/javassist/ClassPool.java | 14 | ||||
-rw-r--r-- | src/main/javassist/ClassPoolTail.java | 14 | ||||
-rw-r--r-- | src/main/javassist/CtClass.java | 7 | ||||
-rw-r--r-- | src/main/javassist/CtClassType.java | 43 | ||||
-rw-r--r-- | src/main/javassist/compiler/Lex.java | 9 | ||||
-rw-r--r-- | src/main/javassist/compiler/MemberCodeGen.java | 36 | ||||
-rw-r--r-- | src/main/javassist/compiler/MemberResolver.java | 32 |
7 files changed, 119 insertions, 36 deletions
diff --git a/src/main/javassist/ClassPool.java b/src/main/javassist/ClassPool.java index 29d8acb5..394c8410 100644 --- a/src/main/javassist/ClassPool.java +++ b/src/main/javassist/ClassPool.java @@ -203,6 +203,20 @@ public class ClassPool { } /** + * Records a name that never exists. For example, a package name + * can be recorded by this method. + * This would improve execution performance + * since <code>get()</code> does not search the class path at all + * if the given name is an invalid name recorded by this method. + * Note that searching the class path takes relatively long time. + * + * @param name a class name (separeted by dot). + */ + public void recordInvalidClassName(String name) { + source.recordInvalidClassName(name); + } + + /** * Returns the <code>Translator</code> object associated with * this <code>ClassPool</code>. */ diff --git a/src/main/javassist/ClassPoolTail.java b/src/main/javassist/ClassPoolTail.java index 5b013bf8..64560147 100644 --- a/src/main/javassist/ClassPoolTail.java +++ b/src/main/javassist/ClassPoolTail.java @@ -17,6 +17,7 @@ package javassist; import java.io.*; import java.util.zip.*; +import java.util.Hashtable; final class ClassPathList { ClassPathList next; @@ -130,10 +131,12 @@ final class JarClassPath implements ClassPath { final class ClassPoolTail extends ClassPool { protected ClassPathList pathList; private Class thisClass; + private Hashtable packages; // should be synchronized. public ClassPoolTail() { pathList = null; thisClass = getClass(); + packages = new Hashtable(); } public String toString() { @@ -150,6 +153,14 @@ final class ClassPoolTail extends ClassPool { return buf.toString(); } + /** + * You can record "System" so that java.lang.System can be quickly + * found although "System" is not a package name. + */ + public void recordInvalidClassName(String name) { + packages.put(name, name); + } + public byte[] write(String classname) throws NotFoundException, IOException { @@ -274,6 +285,9 @@ final class ClassPoolTail extends ClassPool { public InputStream openClassfile(String classname) throws NotFoundException { + if (packages.get(classname) != null) + throw new NotFoundException(classname); + ClassPathList list = pathList; InputStream ins = null; NotFoundException error = null; diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index 8d50a7b6..b4f4e26a 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -35,7 +35,7 @@ public abstract class CtClass { /** * The version number of this release. */ - public static final String version = "2.7 alpha 5"; + public static final String version = "2.7 alpha 6"; /** * Prints the version number and the copyright notice. @@ -486,6 +486,11 @@ public abstract class CtClass { } /** + * @return null if the specified field is not found. + */ + CtField getField2(String name) { return null; } + + /** * Gets all the fields declared in the class. The inherited fields * are not included. * diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index de1b2f19..943f9ea9 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -331,30 +331,33 @@ class CtClassType extends CtClass { } public CtField getField(String name) throws NotFoundException { - try { - return getDeclaredField(name); - } - catch (NotFoundException e) {} + CtField f = getField2(name); + if (f == null) + throw new NotFoundException("field: " + name + " in " + getName()); + else + return f; + } + + CtField getField2(String name) { + CtField df = getDeclaredField2(name); + if (df != null) + return df; try { CtClass[] ifs = getInterfaces(); int num = ifs.length; - for (int i = 0; i < num; ++i) - try { - return ifs[i].getField(name); - } - catch (NotFoundException e) {} - } - catch (NotFoundException e) {} + for (int i = 0; i < num; ++i) { + CtField f = ifs[i].getField2(name); + if (f != null) + return f; + } - try { CtClass s = getSuperclass(); if (s != null) - return s.getField(name); + return s.getField2(name); } catch (NotFoundException e) {} - - throw new NotFoundException(name); + return null; } public CtField[] getDeclaredFields() { @@ -385,6 +388,14 @@ class CtClassType extends CtClass { } public CtField getDeclaredField(String name) throws NotFoundException { + CtField f = getDeclaredField2(name); + if (f == null) + throw new NotFoundException("field: " + name + " in " + getName()); + else + return f; + } + + private CtField getDeclaredField2(String name) { CtField cf = getFieldsCache(); while (cf != null) { if (cf.getName().equals(name)) @@ -393,7 +404,7 @@ class CtClassType extends CtClass { cf = cf.next; } - throw new NotFoundException(name); + return null; } public CtBehavior[] getDeclaredBehaviors() { diff --git a/src/main/javassist/compiler/Lex.java b/src/main/javassist/compiler/Lex.java index baf4742e..76a22fdf 100644 --- a/src/main/javassist/compiler/Lex.java +++ b/src/main/javassist/compiler/Lex.java @@ -293,7 +293,8 @@ public class Lex implements TokenId { token.doubleValue = (double)value; return FloatConstant; } - else if (c2 == 'E' || c2 == 'e' || c2 == '.') { + else if (c2 == 'E' || c2 == 'e' + || c2 == 'D' || c2 == 'd' || c2 == '.') { StringBuffer tbuf = textBuffer; tbuf.setLength(0); tbuf.append(value); @@ -308,7 +309,7 @@ public class Lex implements TokenId { } private int readDouble(StringBuffer sbuf, int c, Token token) { - if (c != 'E' && c != 'e') { + if (c != 'E' && c != 'e' && c != 'D' && c != 'd') { sbuf.append((char)c); for (;;) { c = getc(); @@ -343,7 +344,9 @@ public class Lex implements TokenId { if (c == 'F' || c == 'f') return FloatConstant; else { - ungetc(c); + if (c != 'D' && c != 'd') + ungetc(c); + return DoubleConstant; } } diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java index 8499dfb0..2d1a747a 100644 --- a/src/main/javassist/compiler/MemberCodeGen.java +++ b/src/main/javassist/compiler/MemberCodeGen.java @@ -283,6 +283,7 @@ public class MemberCodeGen extends CodeGen { exprType = CLASS; arrayDim = 0; className = nfe.getField(); // JVM-internal + resolver.recordPackage(className); isStatic = true; } @@ -594,10 +595,9 @@ public class MemberCodeGen extends CodeGen { /* This method also returns a value in resultStatic. */ protected CtField fieldAccess(ASTree expr) throws CompileError { - CtField f = null; - boolean is_static = false; if (expr instanceof Member) { String name = ((Member)expr).get(); + CtField f = null; try { f = thisClass.getField(name); } @@ -606,35 +606,47 @@ public class MemberCodeGen extends CodeGen { throw new NoFieldException(name, expr); } - is_static = Modifier.isStatic(f.getModifiers()); + boolean is_static = Modifier.isStatic(f.getModifiers()); if (!is_static) if (inStaticMethod) throw new CompileError( "not available in a static method: " + name); else bytecode.addAload(0); // this + + resultStatic = is_static; + return f; } else if (expr instanceof Expr) { Expr e = (Expr)expr; int op = e.getOperator(); if (op == MEMBER) { // static member by # (extension by Javassist) - f = resolver.lookupField(((Symbol)e.oprand1()).get(), + CtField f = resolver.lookupField(((Symbol)e.oprand1()).get(), (Symbol)e.oprand2()); - is_static = true; + resultStatic = true; + return f; } else if (op == '.') { + CtField f = null; try { e.oprand1().accept(this); + /* Don't call lookupFieldByJvmName2(). + * The left operand of . is not a class name but + * a normal expression. + */ if (exprType == CLASS && arrayDim == 0) f = resolver.lookupFieldByJvmName(className, (Symbol)e.oprand2()); else badLvalue(); - is_static = Modifier.isStatic(f.getModifiers()); + boolean is_static = Modifier.isStatic(f.getModifiers()); if (is_static) bytecode.addOpcode(POP); + + resultStatic = is_static; + return f; } catch (NoFieldException nfe) { if (nfe.getExpr() != e.oprand1()) @@ -645,9 +657,11 @@ public class MemberCodeGen extends CodeGen { * lookupFieldByJvmName2() throws NoFieldException. */ Symbol fname = (Symbol)e.oprand2(); - f = resolver.lookupFieldByJvmName2(nfe.getField(), - fname, expr); - is_static = true; + String cname = nfe.getField(); + f = resolver.lookupFieldByJvmName2(cname, fname, expr); + resolver.recordPackage(cname); + resultStatic = true; + return f; } } else @@ -656,8 +670,8 @@ public class MemberCodeGen extends CodeGen { else badLvalue(); - resultStatic = is_static; - return f; + resultStatic = false; + return null; // never reach } private static void badLvalue() throws CompileError { diff --git a/src/main/javassist/compiler/MemberResolver.java b/src/main/javassist/compiler/MemberResolver.java index 6e9c33c1..f266ddf8 100644 --- a/src/main/javassist/compiler/MemberResolver.java +++ b/src/main/javassist/compiler/MemberResolver.java @@ -35,6 +35,22 @@ public class MemberResolver implements TokenId { throw new CompileError("fatal"); } + /** + * @param jvmClassName a class name. Not a package name. + */ + public void recordPackage(String jvmClassName) { + String classname = jvmToJavaName(jvmClassName); + for (;;) { + int i = classname.lastIndexOf('.'); + if (i > 0) { + classname = classname.substring(0, i); + classPool.recordInvalidClassName(classname); + } + else + break; + } + } + public static class Method { public CtClass declaring; public MethodInfo info; @@ -336,12 +352,18 @@ public class MemberResolver implements TokenId { return lookupClass0(name, notCheckInner); } catch (NotFoundException e) {} - - try { - if (name.indexOf('.') < 0) - return classPool.get("java.lang." + name); + if (name.indexOf('.') < 0) { + String jlangName = "java.lang." + name; + try { + CtClass cc = classPool.get(jlangName); + // if java.lang... is found, then + classPool.recordInvalidClassName(name); + return cc; + } + catch (NotFoundException e) { + classPool.recordInvalidClassName(jlangName); + } } - catch (NotFoundException e) {} throw new CompileError("no such class: " + name); } |