git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@56 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -537,7 +537,7 @@ public class ClassPool { | |||
void checkNotFrozen(String classname, String errmsg) | |||
throws RuntimeException | |||
{ | |||
CtClass c = (CtClass)classes.get(classname); | |||
CtClass c = getCached(classname); | |||
if (c != null && c.isFrozen()) | |||
throw new RuntimeException(errmsg); | |||
} | |||
@@ -576,7 +576,7 @@ public class ClassPool { | |||
public synchronized CtClass get(String classname) | |||
throws NotFoundException | |||
{ | |||
CtClass clazz = (CtClass)classes.get(classname); | |||
CtClass clazz = getCached(classname); | |||
if (clazz == null) { | |||
clazz = get0(classname); | |||
classes.put(classname, clazz); |
@@ -171,9 +171,7 @@ final class ClassPoolTail extends ClassPool { | |||
throw new RuntimeException("fatal error"); | |||
} | |||
void checkClassName(String classname) | |||
throws NotFoundException | |||
{ | |||
void checkClassName(String classname) throws NotFoundException { | |||
InputStream fin = openClassfile(classname); | |||
try { | |||
fin.close(); |
@@ -35,7 +35,7 @@ public abstract class CtClass { | |||
/** | |||
* The version number of this release. | |||
*/ | |||
public static final String version = "2.7 beta 3"; | |||
public static final String version = "2.7 beta 4"; | |||
/** | |||
* Prints the version number and the copyright notice. | |||
@@ -636,7 +636,7 @@ public abstract class CtClass { | |||
} | |||
/** | |||
* Makes a class initializer (static constructor). | |||
* Makes an empty class initializer (static constructor). | |||
* If the class already includes a class initializer, | |||
* this method returns it. | |||
* | |||
@@ -649,7 +649,10 @@ public abstract class CtClass { | |||
} | |||
/** | |||
* Adds a constructor. | |||
* Adds a constructor. To add a class initializer (static constructor), | |||
* call <code>makeClassInitializer()</code>. | |||
* | |||
* @see #makeClassInitializer() | |||
*/ | |||
public void addConstructor(CtConstructor c) | |||
throws CannotCompileException |
@@ -24,6 +24,11 @@ import javassist.CtMethod.ConstParameter; | |||
* A collection of static methods for creating a <code>CtConstructor</code>. | |||
* An instance of this class does not make any sense. | |||
* | |||
* <p>A class initializer (static constructor) cannot be created by the | |||
* methods in this class. Call <code>makeClassInitializer()</code> in | |||
* <code>CtClass</code> and append code snippet to the body of the class | |||
* initializer obtained by <code>makeClassInitializer()</code>. | |||
* | |||
* @see CtClass#addConstructor(CtConstructor) | |||
*/ | |||
public class CtNewConstructor { |
@@ -263,7 +263,7 @@ public class MemberCodeGen extends CodeGen { | |||
int op = e.getOperator(); | |||
if (op == MEMBER) { // static method | |||
targetClass | |||
= resolver.lookupClass(((Symbol)e.oprand1()).get()); | |||
= resolver.lookupClass(((Symbol)e.oprand1()).get(), false); | |||
isStatic = true; | |||
} | |||
else if (op == '.') { | |||
@@ -287,7 +287,7 @@ public class MemberCodeGen extends CodeGen { | |||
} | |||
if (arrayDim > 0) | |||
targetClass = resolver.lookupClass(javaLangObject); | |||
targetClass = resolver.lookupClass(javaLangObject, true); | |||
else if (exprType == CLASS /* && arrayDim == 0 */) | |||
targetClass = resolver.lookupClassByJvmName(className); | |||
else | |||
@@ -618,6 +618,7 @@ public class MemberCodeGen extends CodeGen { | |||
Expr e = (Expr)expr; | |||
int op = e.getOperator(); | |||
if (op == MEMBER) { | |||
// static member by # (extension by Javassist) | |||
f = resolver.lookupField(((Symbol)e.oprand1()).get(), | |||
(Symbol)e.oprand2()); | |||
is_static = true; | |||
@@ -639,18 +640,14 @@ public class MemberCodeGen extends CodeGen { | |||
if (nfe.getExpr() != e.oprand1()) | |||
throw nfe; | |||
/* EXPR should be a static field. | |||
* If EXPR might be part of a qualified class name, | |||
* lookupFieldByJvmName2() throws NoFieldException. | |||
*/ | |||
Symbol fname = (Symbol)e.oprand2(); | |||
// it should be a static field. | |||
try { | |||
f = resolver.lookupFieldByJvmName(nfe.getField(), | |||
fname); | |||
is_static = true; | |||
} | |||
catch (CompileError ce) { | |||
// EXPR might be part of a qualified class name. | |||
throw new NoFieldException(nfe.getField() + "/" | |||
+ fname.get(), expr); | |||
} | |||
f = resolver.lookupFieldByJvmName2(nfe.getField(), | |||
fname, expr); | |||
is_static = true; | |||
} | |||
} | |||
else |
@@ -208,20 +208,40 @@ public class MemberResolver implements TokenId { | |||
} | |||
/** | |||
* Only used by fieldAccess() in MemberCodeGen. | |||
* | |||
* @param jvmClassName a JVM class name. e.g. java/lang/String | |||
*/ | |||
public CtField lookupFieldByJvmName(String jvmClassName, Symbol fieldName) | |||
throws CompileError | |||
public CtField lookupFieldByJvmName2(String jvmClassName, Symbol fieldSym, | |||
ASTree expr) throws NoFieldException | |||
{ | |||
return lookupField(jvmToJavaName(jvmClassName), fieldName); | |||
String field = fieldSym.get(); | |||
CtClass cc = null; | |||
try { | |||
cc = lookupClass(jvmToJavaName(jvmClassName), true); | |||
} | |||
catch (CompileError e) { | |||
// EXPR might be part of a qualified class name. | |||
throw new NoFieldException(jvmClassName + "/" + field, expr); | |||
} | |||
try { | |||
return cc.getField(field); | |||
} | |||
catch (NotFoundException e) { | |||
// maybe an inner class. | |||
jvmClassName = javaToJvmName(cc.getName()); | |||
throw new NoFieldException(jvmClassName + "$" + field, expr); | |||
} | |||
} | |||
// never used?? | |||
private CtField lookupField2(ASTList className, Symbol fieldName) | |||
/** | |||
* @param jvmClassName a JVM class name. e.g. java/lang/String | |||
*/ | |||
public CtField lookupFieldByJvmName(String jvmClassName, Symbol fieldName) | |||
throws CompileError | |||
{ | |||
return lookupField(Declarator.astToClassName(className, '.'), | |||
fieldName); | |||
return lookupField(jvmToJavaName(jvmClassName), fieldName); | |||
} | |||
/** | |||
@@ -230,7 +250,7 @@ public class MemberResolver implements TokenId { | |||
public CtField lookupField(String className, Symbol fieldName) | |||
throws CompileError | |||
{ | |||
CtClass cc = lookupClass(className); | |||
CtClass cc = lookupClass(className, false); | |||
try { | |||
return cc.getField(fieldName.get()); | |||
} | |||
@@ -239,11 +259,11 @@ public class MemberResolver implements TokenId { | |||
} | |||
public CtClass lookupClassByName(ASTList name) throws CompileError { | |||
return lookupClass(Declarator.astToClassName(name, '.')); | |||
return lookupClass(Declarator.astToClassName(name, '.'), false); | |||
} | |||
public CtClass lookupClassByJvmName(String jvmName) throws CompileError { | |||
return lookupClass(jvmToJavaName(jvmName)); | |||
return lookupClass(jvmToJavaName(jvmName), false); | |||
} | |||
public CtClass lookupClass(Declarator decl) throws CompileError { | |||
@@ -302,15 +322,17 @@ public class MemberResolver implements TokenId { | |||
while (dim-- > 0) | |||
cname += "[]"; | |||
return lookupClass(cname); | |||
return lookupClass(cname, false); | |||
} | |||
/** | |||
* @param name a qualified class name. e.g. java.lang.String | |||
*/ | |||
public CtClass lookupClass(String name) throws CompileError { | |||
public CtClass lookupClass(String name, boolean notCheckInner) | |||
throws CompileError | |||
{ | |||
try { | |||
return classPool.get(name); | |||
return lookupClass0(name, notCheckInner); | |||
} | |||
catch (NotFoundException e) {} | |||
@@ -323,6 +345,28 @@ public class MemberResolver implements TokenId { | |||
throw new CompileError("no such class: " + name); | |||
} | |||
private CtClass lookupClass0(String classname, boolean notCheckInner) | |||
throws NotFoundException | |||
{ | |||
CtClass cc = null; | |||
do { | |||
try { | |||
cc = classPool.get(classname); | |||
} | |||
catch (NotFoundException e) { | |||
int i = classname.lastIndexOf('.'); | |||
if (notCheckInner || i < 0) | |||
throw e; | |||
else { | |||
StringBuffer sbuf = new StringBuffer(classname); | |||
sbuf.setCharAt(i, '$'); | |||
classname = sbuf.toString(); | |||
} | |||
} | |||
} while (cc == null); | |||
return cc; | |||
} | |||
/* Converts a class name into a JVM-internal representation. | |||
* | |||
* It may also expand a simple class name to java.lang.*. |
@@ -441,7 +441,8 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { | |||
int op = e.getOperator(); | |||
if (op == MEMBER) // static method | |||
targetClass | |||
= resolver.lookupClass(((Symbol)e.oprand1()).get()); | |||
= resolver.lookupClass(((Symbol)e.oprand1()).get(), | |||
false); | |||
else if (op == '.') { | |||
ASTree target = e.oprand1(); | |||
try { | |||
@@ -458,7 +459,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { | |||
} | |||
if (arrayDim > 0) | |||
targetClass = resolver.lookupClass(javaLangObject); | |||
targetClass = resolver.lookupClass(javaLangObject, true); | |||
else if (exprType == CLASS /* && arrayDim == 0 */) | |||
targetClass = resolver.lookupClassByJvmName(className); | |||
else | |||
@@ -610,17 +611,13 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { | |||
if (nfe.getExpr() != e.oprand1()) | |||
throw nfe; | |||
/* EXPR should be a static field. | |||
* If EXPR might be part of a qualified class name, | |||
* lookupFieldByJvmName2() throws NoFieldException. | |||
*/ | |||
Symbol fname = (Symbol)e.oprand2(); | |||
// it should be a static field. | |||
try { | |||
return resolver.lookupFieldByJvmName(nfe.getField(), | |||
fname); | |||
} | |||
catch (CompileError ce) { | |||
// EXPR might be part of a qualified class name. | |||
throw new NoFieldException(nfe.getField() + "/" | |||
+ fname.get(), expr); | |||
} | |||
return resolver.lookupFieldByJvmName2(nfe.getField(), | |||
fname, expr); | |||
} | |||
} | |||