]> source.dussan.org Git - javassist.git/commitdiff
modified the compiler to support "import".
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Thu, 18 Aug 2005 15:22:38 +0000 (15:22 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Thu, 18 Aug 2005 15:22:38 +0000 (15:22 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@195 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

src/main/javassist/ClassPool.java
src/main/javassist/CtClass.java
src/main/javassist/compiler/MemberResolver.java
tutorial/tutorial2.html

index 452f2e6f9508645874a4e0f7e05b689a26a32edd..e8b288e5d7705d209190dc8a57b72d748cab7658 100644 (file)
@@ -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.
index eabdb8911607bbac4f36819df552be35e6911be5..b2d6ff1027d7c1f119f6d5a77404a9d0898363c2 100644 (file)
@@ -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());
index fafbe22b41d5f1ca8e21767028f7a2fd001e1c3b..f931c9de40b0cc0e86e9c5624a7cd004b7f7d6e5 100644 (file)
@@ -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)
index 910123b960e87b0d6368525b19be290d73573494..5befd301533da19ab0f3f091931f4e07d95ba5fa 100644 (file)
@@ -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.