Code Search for Developers
 
 
  

TreeCompiler.java from DrJava at Krugle


Show TreeCompiler.java syntax highlighted

/*
 * DynamicJava - Copyright (C) 1999-2001
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL DYADE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Dyade shall not be
 * used in advertising or otherwise to promote the sale, use or other
 * dealings in this Software without prior written authorization from
 * Dyade.
 *
 */

package koala.dynamicjava.interpreter;

import java.io.*;
import java.util.*;

import koala.dynamicjava.classinfo.*;
import koala.dynamicjava.interpreter.context.*;
import koala.dynamicjava.interpreter.error.*;
import koala.dynamicjava.parser.wrapper.*;
import koala.dynamicjava.tree.*;
import koala.dynamicjava.tree.visitor.*;
import koala.dynamicjava.util.*;

/**
 * This class contains methods to manage the creation of classes.
 *
 * @author  Stephane Hillion
 * @version 1.1 - 1999/11/28
 */

public class TreeCompiler {
  /**
   * The interpreter
   */
  protected Interpreter interpreter;
  
  /**
   * The classloader
   */
  protected TreeClassLoader classLoader;
  
  /**
   * The class info loader
   */
  protected ClassInfoLoader classInfoLoader;
  
  /**
   * The class pool
   */
  protected ClassPool classPool = new ClassPool();
  
  /**
   * Creates a new compiler
   * @param i the current interpreter
   */
  public TreeCompiler(Interpreter i) {
    interpreter     = i;
    classLoader     = (TreeClassLoader)interpreter.getClassLoader();
    classInfoLoader = new ClassInfoLoader();
  }
  
  /**
   * Compiles a compilation unit
   * @param name the name of the class to compile
   */
  public Class<?> compile(String name) throws ClassNotFoundException {
    loadClass(name);
    return compileClasses(name);
  }
  
  /**
   * Compiles all the classes in the class pool
   * @param name the name of the class to return
   */
  public Class<?> compileClasses(String name) throws ClassNotFoundException {
    Class<?> result = null;
    if (classPool.contains(name)) {
      ClassInfo ci;
      while ((ci = classPool.getFirstCompilable()) != null) {
        if (!classExists(ci.getName())) {
          Class<?> c = compileClass(ci, name);
          if (c != null) {
            result = c;
          }
        } else {
          ci.setCompilable(false);
        }
      }
    }
    
    if (result == null) {
      throw new ClassNotFoundException(name);
    }
    return result;
  }
  
  /**
   * Compiles a single class
   * @param td the type declaration
   * @param im the importation manager
   */
  public Class<?> compileTree(Context ctx, TypeDeclaration td) {
    ClassFinder cf = new TreeClassFinder(ctx, interpreter, classPool);
    ClassInfo   ci = new TreeClassInfo(td, cf);
    classPool.add(ci.getName(), ci);
    try {
      return compileClasses(ci.getName());
    } catch (ClassNotFoundException e) {
      td.setProperty(NodeProperties.ERROR_STRINGS,
                     new String[] { td.getName() });
      throw new ExecutionError("undefined.or.defined.class", td);
    }
  }
  
  /**
   * Compiles the given class info
   * @param ci   the class info to compile
   * @param name the name of the class to return
   */
  protected Class<?> compileClass(ClassInfo ci, String name) {
    Class<?> result = null;
    
    // Compile first the superclass and interfaces if needed
    ClassInfo t = ci.getSuperclass();
    if (t.isCompilable() && !classExists(t.getName())) {
      Class<?> c = compileClass(t, name);
      if (c != null) {
        result = c;
      }
    }
    
    ClassInfo [] ti = ci.getInterfaces();
    for (int i = 0; i < ti.length; i++) {
      t = ti[i];
      if (t.isCompilable() && !classExists(t.getName())) {
        Class<?> c = compileClass(t, name);
        if (c != null) {
          result = c;
        }
      }
    }
    
    // Then compile the class
    Class<?> c = new ClassInfoCompiler(ci).compile();
    ci.setCompilable(false);
    if (name.equals(c.getName())) {
      result = c;
    }
    
    return result;
  }
  
  /**
   * Whether a class exists in a compiled form
   */
  protected boolean classExists(String name) {
    return classLoader.hasDefined(name);
  }
  
  /**
   * Searches for a class, loads its class info structure
   */
  protected void loadClass(String name) throws ClassNotFoundException {
    if (classPool.contains(name)) {
      return;
    }
    
    // Is there a tree associated with this name ?
    TypeDeclaration td = classLoader.getTree(name);
    if (td != null) {
      ImportationManager im = (ImportationManager)td.getProperty
        (NodeProperties.IMPORTATION_MANAGER);
      Context ctx = new GlobalContext(interpreter, classInfoLoader);
      im.setClassLoader(classInfoLoader);
      ctx.setImportationManager(im);
      ClassFinder cfinder = new TreeClassFinder(ctx,
                                                interpreter,
                                                classPool);
      classPool.add(name, new TreeClassInfo(td, cfinder));
      return;
    }
    
    // Is the class tree already loaded ?
    LibraryFinder lf = interpreter.getLibraryFinder();
    try {
      String cun = lf.findCompilationUnitName(name);
      td = classLoader.getTree(cun);
      if (td != null) {
        ImportationManager im = (ImportationManager)td.getProperty
          (NodeProperties.IMPORTATION_MANAGER);
        Context ctx = new GlobalContext(interpreter, classInfoLoader);
        im.setClassLoader(classInfoLoader);
        ctx.setImportationManager(im);
        ClassFinder cfinder = new TreeClassFinder(ctx,
                                                  interpreter,
                                                  classPool);
        classPool.add(cun, new TreeClassInfo(td, cfinder));
        return;
      }
    } catch (ClassNotFoundException e) {
    }
    
    try {
      File f = lf.findCompilationUnit(name);
      FileInputStream fis = new FileInputStream(f);
      
      ParserFactory pf = interpreter.getParserFactory();
      SourceCodeParser p = pf.createParser(fis, f.getCanonicalPath());
      List<Node> stmts = p.parseCompilationUnit();
      
      Iterator<Node> it = stmts.iterator();
      CompilationUnitVisitor v  = new CompilationUnitVisitor();
      while (it.hasNext()) {
        it.next().acceptVisitor(v);
      }
    } catch (IOException e) {
      throw new ClassNotFoundException(name);
    }
  }
  
  /**
   * To create the class infos for a compilation unit
   */
  protected class CompilationUnitVisitor extends VisitorObject<Void> {
    /**
     * The context
     */
    protected Context context = new GlobalContext(interpreter, classInfoLoader);
    
    /**
     * The class finder
     */
    protected ClassFinder classFinder = new TreeClassFinder(context,
                                                            interpreter,
                                                            classPool);
    
    /**
     * Visits a PackageDeclaration
     * @param node the node to visit
     * @return null
     */
    public Void visit(PackageDeclaration node) {
      context.setCurrentPackage(node.getName());
      return null;
    }
    
    /**
     * Visits an ImportDeclaration
     * @param node the node to visit
     */
    public Void visit(ImportDeclaration node) {
      if(node.isStatic()) {       
        TigerUtilities.assertTigerEnabled("Static Import is not supported before Java 1.5");
        try {
          if(node.isStaticImportClass()) 
            context.declareClassStaticImport(node.getName());
          else 
            context.declareMemberStaticImport(node.getName());
          // Declare the package or class importation
        } catch (ClassNotFoundException e) {
          throw new CatchedExceptionError(e, node);
        }
      }
      else {
        if (node.isPackage()) {
          context.declarePackageImport(node.getName());
        } else {
          try {
            context.declareClassImport(node.getName());
          } catch (ClassNotFoundException e) {
            throw new CatchedExceptionError(e, node);
          } catch (PseudoError e) {
          }
        }
      }
      return null;
    }
    
    /**
     * Visits a ClassDeclaration
     * @param node the node to visit
     */
    public Void visit(ClassDeclaration node) {
      return visitType(node);
    }
    
    /**
     * Visits an InterfaceDeclaration
     * @param node the node to visit
     */
    public Void visit(InterfaceDeclaration node) {
      return visitType(node);
    }
    
    /**
     * Visits a type declaration
     * @param node the node to visit
     */
    protected Void visitType(TypeDeclaration node) {
      String cname = classFinder.getCurrentPackage();
      cname = ((cname.equals("")) ? "" : cname + "." ) + node.getName();
      classPool.add(cname, new TreeClassInfo(node, classFinder));
      return null;
    }
  }
  
  /**
   * To load class infos instead of classes
   */
  protected class ClassInfoLoader extends ClassLoader {
    /**
     * Finds the specified class.
     * @param  name the name of the class
     * @return the resulting <code>Class</code> object
     * @exception ClassNotFoundException if the class could not be find
     */
    protected Class<?> findClass(String name) throws ClassNotFoundException {
      TreeCompiler.this.loadClass(name);
      if (classPool.contains(name)) {
        throw new PseudoError(classPool.get(name));
      } else {
        throw new ClassNotFoundException(name);
      }
    }
  }
  
  /**
   * To test the existance of a class without loading it
   */
  public class PseudoError extends Error {
    /**
     * The exception content
     */
    protected ClassInfo classInfo;
    
    /**
     * Creates a new error
     */
    PseudoError(ClassInfo ci) {
      classInfo = ci;
    }
    
    /**
     * Returns the class info
     */
    public ClassInfo getClassInfo() {
      return classInfo;
    }
  }
}




See more files for this project here

DrJava

DrJava is a lightweight programming environment for Java designed to foster test-driven software development. It includes an intelligent program editor, an interactions pane for evaluating program text, a source level debugger, and a unit testing tool.

Project homepage: http://sourceforge.net/projects/drjava
Programming language(s): Java
License: other

  context/
    AbstractVariable.java
    Context.java
    GlobalContext.java
    MethodContext.java
    MethodModificationError.java
    NoSuchFunctionException.java
    NoSuchKeyException.java
    SimpleContext.java
    StaticContext.java
    VariableContext.java
    VariableContextTest.java
    package.html
  error/
    BreakException.java
    CatchedExceptionError.java
    ContinueException.java
    ExecutionError.java
    PossibleExecutionError.java
    ReturnException.java
    ThrownException.java
    WrongVersionException.java
    package.html
  modifier/
    ArrayModifier.java
    FinalVariableModifier.java
    InvalidModifier.java
    LeftHandSideModifier.java
    ObjectFieldModifier.java
    StaticFieldModifier.java
    SuperFieldModifier.java
    VariableModifier.java
    package.html
  resources/
    messages.properties
  AbstractTypeChecker.java
  ClassFactory.java
  ClassInfoCompiler.java
  ClassLoaderContainer.java
  ClassPool.java
  DynamicjavaTest.java
  EvaluationVisitor.java
  EvaluationVisitorTest.java
  ForEachNamingTest.java
  ForEachTypingTest.java
  Interpreter.java
  InterpreterException.java
  InterpreterUtilities.java
  Main.java
  NameVisitor.java
  NodeProperties.java
  TreeClassFinder.java
  TreeClassLoader.java
  TreeCompiler.java
  TreeInterpreter.java
  Type.ast
  TypeChecker14.java
  TypeChecker15.java
  TypeCheckerTest.java
  TypeVariable.java
  UninitializedObject.java
  package.html