From 2d60b1690e44dd33553e28618c7c0b25e4b34d9f Mon Sep 17 00:00:00 2001 From: chiba Date: Thu, 18 Aug 2005 15:22:38 +0000 Subject: [PATCH] modified the compiler to support "import". git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@195 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- src/main/javassist/ClassPool.java | 45 ++++++++++++++++++ src/main/javassist/CtClass.java | 2 + .../javassist/compiler/MemberResolver.java | 36 ++++++++++----- tutorial/tutorial2.html | 46 +++++++++++++++---- 4 files changed, 109 insertions(+), 20 deletions(-) diff --git a/src/main/javassist/ClassPool.java b/src/main/javassist/ClassPool.java index 452f2e6f..e8b288e5 100644 --- a/src/main/javassist/ClassPool.java +++ b/src/main/javassist/ClassPool.java @@ -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 java.lang package, which has + * been implicitly recorded by default. + * + *

Note that get() in ClassPool 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 importPackage(). + * The java.lang 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 importPackage(). + * + * @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. diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index eabdb891..b2d6ff10 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -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()); diff --git a/src/main/javassist/compiler/MemberResolver.java b/src/main/javassist/compiler/MemberResolver.java index fafbe22b..f931c9de 100644 --- a/src/main/javassist/compiler/MemberResolver.java +++ b/src/main/javassist/compiler/MemberResolver.java @@ -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) diff --git a/tutorial/tutorial2.html b/tutorial/tutorial2.html index 910123b9..5befd301 100644 --- a/tutorial/tutorial2.html +++ b/tutorial/tutorial2.html @@ -19,6 +19,7 @@

  • Altering a method body
  • Adding a new method or field
  • Runtime support classes +
  • Import
  • Limitations @@ -1456,8 +1457,44 @@ Javassist classes are never used at runtime of the modified classes.


    + +

    4.5 Import

    + +

    All the class names in source code must be fully qualified +(they must include package names). +However, the java.lang package is an +exception; for example, the Javassist compiler can +resolve Object as +well as java.lang.Object. + +

    To tell the compiler to search other packages when resolving a +class name, call importPackage() in ClassPool. +For example, + +

      +ClassPool pool = ClassPool.getDefault();
      +pool.importPackage("java.awt");
      +CtClass cc = pool.makeClass("Test");
      +CtField f = CtField.make("public Point p;", cc);
      +cc.addField(f);
      +
    + +

    The seconde line instructs the compiler +to import the java.awt package. +Thus, the third line will not throw an exception. +The compiler can recognize Point +as java.awt.Point. + +

    Note that importPackage() does not affect +the get() method in ClassPool. +Only the compiler considers the imported packages. +The parameter to get() +must be always a fully qualified name. + +


    +
    -

    4.5 Limitations

    +

    4.6 Limitations

    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 javassist.bytecode.annotation package. -

  • All the class names must be fully qualified (they must include -package names). This is because the compiler does not support -import -declarations. However, the java.lang package is an -exception; for example, the compiler accepts Object as -well as java.lang.Object. -

  • Array initializers, a comma-separated list of expressions enclosed by braces { and }, are not supported. -- 2.39.5