summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/javassist/ClassPool.java14
-rw-r--r--src/main/javassist/ClassPoolTail.java14
-rw-r--r--src/main/javassist/CtClass.java7
-rw-r--r--src/main/javassist/CtClassType.java43
-rw-r--r--src/main/javassist/compiler/Lex.java9
-rw-r--r--src/main/javassist/compiler/MemberCodeGen.java36
-rw-r--r--src/main/javassist/compiler/MemberResolver.java32
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);
}