git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@195 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -22,6 +22,8 @@ import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.net.URL; | |||
import java.util.Hashtable; | |||
import java.util.Iterator; | |||
import java.util.ArrayList; | |||
import javassist.bytecode.Descriptor; | |||
/** | |||
@@ -111,6 +113,8 @@ public class ClassPool { | |||
private static final int INIT_HASH_SIZE = 191; | |||
private ArrayList importedPackages; | |||
/** | |||
* Creates a root class pool. No parent class pool is specified. | |||
*/ | |||
@@ -136,6 +140,7 @@ public class ClassPool { | |||
} | |||
this.cflow = null; | |||
clearImportedPackages(); | |||
} | |||
/** | |||
@@ -213,6 +218,46 @@ public class ClassPool { | |||
return source.toString(); | |||
} | |||
/** | |||
* Record a package name so that the Javassist compiler searches | |||
* the package to resolve a class name. | |||
* Don't record the <code>java.lang</code> package, which has | |||
* been implicitly recorded by default. | |||
* | |||
* <p>Note that <code>get()</code> in <code>ClassPool</code> does | |||
* not search the recorded package. Only the compiler searches it. | |||
* | |||
* @param packageName the package name. | |||
* It must not include the last '.' (dot). | |||
* For example, "java.util" is valid but "java.util." is wrong. | |||
* @since 3.1 | |||
*/ | |||
public void importPackage(String packageName) { | |||
importedPackages.add(packageName); | |||
} | |||
/** | |||
* Clear all the package names recorded by <code>importPackage()</code>. | |||
* The <code>java.lang</code> package is not removed. | |||
* | |||
* @see #importPackage(String) | |||
* @since 3.1 | |||
*/ | |||
public void clearImportedPackages() { | |||
importedPackages = new ArrayList(); | |||
importedPackages.add("java.lang"); | |||
} | |||
/** | |||
* Returns all the package names recorded by <code>importPackage()</code>. | |||
* | |||
* @see #importPackage(String) | |||
* @since 3.1 | |||
*/ | |||
public Iterator getImportedPackages() { | |||
return importedPackages.iterator(); | |||
} | |||
/** | |||
* Records a name that never exists. | |||
* For example, a package name can be recorded by this method. |
@@ -235,6 +235,7 @@ public abstract class CtClass { | |||
* and thus it cannot be modified any more. | |||
* | |||
* @see #defrost() | |||
* @see #detach() | |||
*/ | |||
public boolean isFrozen() { return true; } | |||
@@ -260,6 +261,7 @@ public abstract class CtClass { | |||
* | |||
* @see #isFrozen() | |||
* @see #stopPruning(boolean) | |||
* @see #detach() | |||
*/ | |||
public void defrost() { | |||
throw new RuntimeException("cannot defrost " + getName()); |
@@ -16,6 +16,7 @@ | |||
package javassist.compiler; | |||
import java.util.List; | |||
import java.util.Iterator; | |||
import javassist.*; | |||
import javassist.bytecode.*; | |||
import javassist.compiler.ast.*; | |||
@@ -354,21 +355,32 @@ public class MemberResolver implements TokenId { | |||
try { | |||
return lookupClass0(name, notCheckInner); | |||
} | |||
catch (NotFoundException e) {} | |||
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) { | |||
return searchImports(name); | |||
} | |||
} | |||
private CtClass searchImports(String orgName) | |||
throws CompileError | |||
{ | |||
if (orgName.indexOf('.') < 0) { | |||
Iterator it = classPool.getImportedPackages(); | |||
while (it.hasNext()) { | |||
String pac = (String)it.next(); | |||
String fqName = pac + '.' + orgName; | |||
try { | |||
CtClass cc = classPool.get(fqName); | |||
// if the class is found, | |||
classPool.recordInvalidClassName(orgName); | |||
return cc; | |||
} | |||
catch (NotFoundException e) { | |||
classPool.recordInvalidClassName(fqName); | |||
} | |||
} | |||
} | |||
throw new CompileError("no such class: " + name); | |||
throw new CompileError("no such class: " + orgName); | |||
} | |||
private CtClass lookupClass0(String classname, boolean notCheckInner) |
@@ -19,6 +19,7 @@ | |||
<br><li><a href="#alter">Altering a method body</a> | |||
<br><li><a href="#add">Adding a new method or field</a> | |||
<br><li><a href="#runtime">Runtime support classes</a> | |||
<br><li><a href="#import">Import</a> | |||
<br><li><a href="#limit">Limitations</a> | |||
</ul> | |||
@@ -1456,8 +1457,44 @@ Javassist classes are never used at runtime of the modified classes. | |||
<p><br> | |||
<a name="import"> | |||
<h3>4.5 Import</h3> | |||
<p>All the class names in source code must be fully qualified | |||
(they must include package names). | |||
However, the <code>java.lang</code> package is an | |||
exception; for example, the Javassist compiler can | |||
resolve <code>Object</code> as | |||
well as <code>java.lang.Object</code>. | |||
<p>To tell the compiler to search other packages when resolving a | |||
class name, call <code>importPackage()</code> in <code>ClassPool</code>. | |||
For example, | |||
<ul><pre> | |||
ClassPool pool = ClassPool.getDefault(); | |||
pool.importPackage("java.awt"); | |||
CtClass cc = pool.makeClass("Test"); | |||
CtField f = CtField.make("public Point p;", cc); | |||
cc.addField(f); | |||
</pre></ul> | |||
<p>The seconde line instructs the compiler | |||
to import the <code>java.awt</code> package. | |||
Thus, the third line will not throw an exception. | |||
The compiler can recognize <code>Point</code> | |||
as <code>java.awt.Point</code>. | |||
<p>Note that <code>importPackage()</code> <em>does not</em> affect | |||
the <code>get()</code> method in <code>ClassPool</code>. | |||
Only the compiler considers the imported packages. | |||
The parameter to <code>get()</code> | |||
must be always a fully qualified name. | |||
<p><br> | |||
<a name="limit"> | |||
<h3>4.5 Limitations</h3> | |||
<h3>4.6 Limitations</h3> | |||
<p>In the current implementation, the Java compiler included in Javassist | |||
has several limitations with respect to the language that the compiler can | |||
@@ -1468,13 +1505,6 @@ has not been supported. Annotations are supported only by the low level | |||
API of Javassist. | |||
See the <code>javassist.bytecode.annotation</code> package. | |||
<p><li>All the class names must be fully qualified (they must include | |||
package names). This is because the compiler does not support | |||
<code>import</code> | |||
declarations. However, the <code>java.lang</code> package is an | |||
exception; for example, the compiler accepts <code>Object</code> as | |||
well as <code>java.lang.Object</code>. | |||
<p><li>Array initializers, a comma-separated list of expressions | |||
enclosed by braces <code>{</code> and <code>}</code>, are not | |||
supported. |