Remy Sanlaville, Muga Nishizawa, Alexey Loubyansky, Saori Oki,
Andreas Salathe, Dante Torres estrada, S. Pam, Nuno Santos,
Denis Taye, Colin Sampaleanu, Robert Bialek, Asato Shimotaki,
-and Howard Lewis Ship for their contributions.
+Howard Lewis Ship, and Richard Jones for their contributions.
<p><br>
return source.toString();
}
+ /**
+ * 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>.
import java.io.*;
import java.util.zip.*;
+import java.util.Hashtable;
final class ClassPathList {
ClassPathList next;
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() {
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
{
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;
/**
* 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.
throw new NotFoundException(name);
}
+ /**
+ * @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.
}
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() {
}
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))
cf = cf.next;
}
- throw new NotFoundException(name);
+ return null;
}
public CtBehavior[] getDeclaredBehaviors() {
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);
}
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();
if (c == 'F' || c == 'f')
return FloatConstant;
else {
- ungetc(c);
+ if (c != 'D' && c != 'd')
+ ungetc(c);
+
return DoubleConstant;
}
}
exprType = CLASS;
arrayDim = 0;
className = nfe.getField(); // JVM-internal
+ resolver.recordPackage(className);
isStatic = true;
}
/* 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);
}
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())
* 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
else
badLvalue();
- resultStatic = is_static;
- return f;
+ resultStatic = false;
+ return null; // never reach
}
private static void badLvalue() throws CompileError {
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;
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);
}