/*
 * Copyright 1994-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.tools.javac;

import sun.tools.java.*;
import sun.tools.tree.Node;
import sun.tools.java.Package;

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

/**
 * Main environment of the batch version of the Java compiler,
 * this needs more work.
 *
 * WARNING: The contents of this source file are not part of any
 * supported API.  Code that depends on them does so at its own risk:
 * they are subject to change or removal without notice.
 */
@Deprecated
public
class BatchEnvironment extends Environment implements ErrorConsumer {
    /**
     * The stream where error message are printed.
     */
    OutputStream out;

    /**
     * The path we use for finding source files.
     */
    protected ClassPath sourcePath;

    /**
     * The path we use for finding class (binary) files.
     */
    protected ClassPath binaryPath;

    /**
     * A hashtable of resource contexts.
     */
    Hashtable packages = new Hashtable(31);

    /**
     * The classes, in order of appearance.
     */
    Vector classesOrdered = new Vector();

    /**
     * The classes, keyed by ClassDeclaration.
     */
    Hashtable classes = new Hashtable(351);

    /**
     * flags
     */
    public int flags;

    /**
     * Major and minor versions to use for generated class files.
     * Environments that extend BatchEnvironment (such as javadoc's
     * Env class) get the default values below.
     *
     * javac itself may override these versions with values determined
     * from the command line "-target" option.
     */
    public short majorVersion = JAVA_DEFAULT_VERSION;
    public short minorVersion = JAVA_DEFAULT_MINOR_VERSION;

// JCOV
    /**
     * coverage data file
     */
    public File covFile;
// end JCOV

    /**
     * The number of errors and warnings
     */
    public int nerrors;
    public int nwarnings;
    public int ndeprecations;

    /**
     * A list of files containing deprecation warnings.
     */
    Vector deprecationFiles = new Vector();

        /**
         * writes out error messages
         */

        ErrorConsumer errorConsumer;

    /**
     * Old constructors -- these constructors build a BatchEnvironment
     * with an old-style class path.
     */
    public BatchEnvironment(ClassPath path) {
        this(System.out, path);
    }
    public BatchEnvironment(OutputStream out,
                            ClassPath path) {
        this(out, path, (ErrorConsumer) null);
    }
    public BatchEnvironment(OutputStream out,
                            ClassPath path,
                            ErrorConsumer errorConsumer) {
        this(out, path, path, errorConsumer);
    }

    /**
     * New constructors -- these constructors build a BatchEnvironment
     * with a source path and a binary path.
     */
    public BatchEnvironment(ClassPath sourcePath,
                            ClassPath binaryPath) {
        this(System.out, sourcePath, binaryPath);
    }
    public BatchEnvironment(OutputStream out,
                            ClassPath sourcePath,
                            ClassPath binaryPath) {
        this(out, sourcePath, binaryPath, (ErrorConsumer) null);
    }
    public BatchEnvironment(OutputStream out,
                            ClassPath sourcePath,
                            ClassPath binaryPath,
                            ErrorConsumer errorConsumer) {
        this.out = out;
        this.sourcePath = sourcePath;
        this.binaryPath = binaryPath;
        this.errorConsumer = (errorConsumer == null) ? this : errorConsumer;
    }

    /**
     * Factory
     */
    static BatchEnvironment create(OutputStream out,
                                   String srcPathString,
                                   String classPathString,
                                   String sysClassPathString,
                                   String extDirsString){
        ClassPath[] classPaths = classPaths(srcPathString, classPathString,
                                            sysClassPathString, extDirsString);
        return new BatchEnvironment(out, classPaths[0], classPaths[1]);
    }

    protected static ClassPath[] classPaths(String srcPathString,
                                            String classPathString,
                                            String sysClassPathString,
                                            String extDirsString) {
        // Create our source classpath and our binary classpath
        ClassPath sourcePath;
        ClassPath binaryPath;
        StringBuffer binaryPathBuffer = new StringBuffer();

        if (classPathString == null) {
            // The env.class.path property is the user's CLASSPATH
            // environment variable, and it set by the wrapper (ie,
            // javac.exe).
            classPathString = System.getProperty("env.class.path");
            if (classPathString == null) {
                classPathString = ".";
            }
        }
        if (srcPathString == null) {
            srcPathString = classPathString;
        }
        if (sysClassPathString == null) {
            sysClassPathString = System.getProperty("sun.boot.class.path");
            if (sysClassPathString == null) { // shouldn't happen; recover gracefully
                sysClassPathString = classPathString;
            }
        }
        appendPath(binaryPathBuffer, sysClassPathString);

        if (extDirsString == null) {
            extDirsString = System.getProperty("java.ext.dirs");
        }
        if (extDirsString != null) {
            StringTokenizer st = new StringTokenizer(extDirsString,
                                                     File.pathSeparator);
            while (st.hasMoreTokens()) {
                String dirName = st.nextToken();
                File dir = new File(dirName);
                if (!dirName.endsWith(File.separator)) {
                    dirName += File.separator;
                }
                if (dir.isDirectory()) {
                    String[] files = dir.list();
                    for (int i = 0; i < files.length; ++i) {
                        String name = files[i];
                        if (name.endsWith(".jar")) {
                            appendPath(binaryPathBuffer, dirName + name);
                        }
                    }
                }
            }
        }

        appendPath(binaryPathBuffer, classPathString);

        sourcePath = new ClassPath(srcPathString);
        binaryPath = new ClassPath(binaryPathBuffer.toString());

        return new ClassPath[]{sourcePath, binaryPath};
    }

    private static void appendPath(StringBuffer buf, String str) {
        if (str.length() > 0) {
            if (buf.length() > 0) {
                buf.append(File.pathSeparator);
            }
            buf.append(str);
        }
    }

    /**
     * Return flags
     */
    public int getFlags() {
        return flags;
    }

    /**
     * Return major version to use for generated class files
     */
    public short getMajorVersion() {
        return majorVersion;
    }

    /**
     * Return minor version to use for generated class files
     */
    public short getMinorVersion() {
        return minorVersion;
    }

// JCOV
    /**
     * Return coverage data file
     */
    public File getcovFile() {
        return covFile;
    }
// end JCOV

    /**
     * Return an enumeration of all the currently defined classes
     * in order of appearance to getClassDeclaration().
     */
    public Enumeration getClasses() {
        return classesOrdered.elements();
    }

    /**
     * A set of Identifiers for all packages exempt from the "exists"
     * check in Imports#resolve().  These are the current packages for
     * all classes being compiled as of the first call to isExemptPackage.
     */
    private Set exemptPackages;

    /**
     * Tells whether an Identifier refers to a package which should be
     * exempt from the "exists" check in Imports#resolve().
     */
    public boolean isExemptPackage(Identifier id) {
        if (exemptPackages == null) {
            // Collect a list of the packages of all classes currently
            // being compiled.
            setExemptPackages();
        }

        return exemptPackages.contains(id);
    }

    /**
     * Set the set of packages which are exempt from the exists check
     * in Imports#resolve().
     */
    private void setExemptPackages() {
        // The JLS gives us the freedom to define "accessibility" of
        // a package in whatever manner we wish.  After the evaluation
        // of bug 4093217, we have decided to consider a package P
        // accessible if either:
        //
        // 1. The directory corresponding to P exists on the classpath.
        // 2. For any class C currently being compiled, C belongs to
        //    package P.
        // 3. For any class C currently being compiled, C belongs to
        //    package Q and Q is a subpackage of P.
        //
        // In order to implement this, we collect the current packages
        // (and prefixes) of all packages we have found so far.  These
        // will be exempt from the "exists" check in
        // sun.tools.java.Imports#resolve().

        exemptPackages = new HashSet(101);

        // Add all of the current packages and their prefixes to our set.
        for (Enumeration e = getClasses(); e.hasMoreElements(); ) {
            ClassDeclaration c = (ClassDeclaration) e.nextElement();
            if (c.getStatus() == CS_PARSED) {
                SourceClass def = (SourceClass) c.getClassDefinition();
                if (def.isLocal())
                    continue;

                Identifier pkg = def.getImports().getCurrentPackage();

                // Add the name of this package and all of its prefixes
                // to our set.
                while (pkg != idNull && exemptPackages.add(pkg)) {
                    pkg = pkg.getQualifier();
                }
            }
        }

        // Before we go any further, we make sure java.lang is
        // accessible and that it is not ambiguous.  These checks
        // are performed for "ordinary" packages in
        // sun.tools.java.Imports#resolve().  The reason we perform
        // them specially for java.lang is that we want to report
        // the error once, and outside of any particular file.

        // Check to see if java.lang is accessible.
        if (!exemptPackages.contains(idJavaLang)) {
            // Add java.lang to the set of exempt packages.
            exemptPackages.add(idJavaLang);

            try {
                if (!getPackage(idJavaLang).exists()) {
                    // java.lang doesn't exist.
                    error(0, "package.not.found.strong", idJavaLang);
                    return;
                }
            } catch (IOException ee) {
                // We got an IO exception checking to see if the package
                // java.lang exists.
                error(0, "io.exception.package", idJavaLang);
            }
        }

        // Next we ensure that java.lang is not both a class and
        // a package.  (Fix for 4101529)
        //
        // This change has been backed out because, on WIN32, it
        // failed to take character case into account.  It will
        // be put back in later.
        //
        // Identifier resolvedName =
        //   resolvePackageQualifiedName(idJavaLang);
        // Identifier topClassName = resolvedName.getTopName();
        //     //if (Imports.importable(topClassName, env)) {
        // if (Imports.importable(topClassName, this)) {
        //    // It is a package and a class.  Emit the error.
        //    error(0, "package.class.conflict.strong",
        //            idJavaLang, topClassName);
        //    return;
        // }
    }

    /**
     * Get a class, given the fully qualified class name
     */
    public ClassDeclaration getClassDeclaration(Identifier nm) {
        return getClassDeclaration(Type.tClass(nm));
    }

    public ClassDeclaration getClassDeclaration(Type t) {
        ClassDeclaration c = (ClassDeclaration)classes.get(t);
        if (c == null) {
            classes.put(t, c = new ClassDeclaration(t.getClassName()));
            classesOrdered.addElement(c);
        }
        return c;
    }

    /**
     * Check if a class exists
     * Applies only to package members (non-nested classes).
     */
    public boolean classExists(Identifier nm) {
        if (nm.isInner()) {
            nm = nm.getTopName();       // just in case
        }
        Type t = Type.tClass(nm);
        try {
            ClassDeclaration c = (ClassDeclaration)classes.get(t);
            return (c != null) ? c.getName().equals(nm) :
                getPackage(nm.getQualifier()).classExists(nm.getName());
        } catch (IOException e) {
            return true;
        }
    }

    /**
     * Generate a new name similar to the given one.
     * Do it in such a way that repeated compilations of
     * the same source generate the same series of names.
     */

    // This code does not perform as stated above.
    // Correction below is part of fix for bug id 4056065.
    //
    // NOTE: The method 'generateName' has now been folded into its
    // single caller, 'makeClassDefinition', which appears later in
    // this file.

    /*--------------------------*
    public Identifier generateName(ClassDefinition outerClass, Identifier nm) {
        Identifier outerNm = outerClass.getName();
        Identifier flat = outerNm.getFlatName();
        Identifier stem = Identifier.lookup(outerNm.getQualifier(),
                                            flat.getHead());
        for (int i = 1; ; i++) {
            String name = i + (nm.equals(idNull) ? "" : SIG_INNERCLASS + nm);
            Identifier nm1 = Identifier.lookupInner(stem,
                                                    Identifier.lookup(name));
            if (classes.get(Type.tClass(nm1)) == null)
                return nm1;
        }
    }
    *--------------------------*/

    /**
     * Get the package path for a package
     */
    public Package getPackage(Identifier pkg) throws IOException {
        Package p = (Package)packages.get(pkg);
        if (p == null) {
            packages.put(pkg, p = new Package(sourcePath, binaryPath, pkg));
        }
        return p;
    }

    /**
     * Parse a source file
     */
    public void parseFile(ClassFile file) throws FileNotFoundException {
        long tm = System.currentTimeMillis();
        InputStream input;
        BatchParser p;

        if (tracing) dtEnter("parseFile: PARSING SOURCE " + file);

        Environment env = new Environment(this, file);

        try {
            input = file.getInputStream();
            env.setCharacterEncoding(getCharacterEncoding());
            //      p = new BatchParser(e, new BufferedInputStream(input));
            p = new BatchParser(env, input);
        } catch(IOException ex) {
            if (tracing) dtEvent("parseFile: IO EXCEPTION " + file);
            throw new FileNotFoundException();
        }

        try {
            p.parseFile();
        } catch(Exception e) {
            throw new CompilerError(e);
        }

        try {
            input.close();
        } catch (IOException ex) {
            // We're turn with the input, so ignore this.
        }

        if (verbose()) {
            tm = System.currentTimeMillis() - tm;
            output(Main.getText("benv.parsed_in", file.getPath(),
                                Long.toString(tm)));
        }

        if (p.classes.size() == 0) {
            // The JLS allows a file to contain no compilation units --
            // that is, it allows a file to contain no classes or interfaces.
            // In this case, we are still responsible for checking that the
            // imports resolve properly.  The way the compiler is organized,
            // this is the last point at which we still have enough information
            // to do so. (Fix for 4041851).
            p.imports.resolve(env);
        } else {
            // In an attempt to see that classes which come from the
            // same source file are all recompiled when any one of them
            // would be recompiled (when using the -depend option) we
            // introduce artificial dependencies between these classes.
            // We do this by calling the addDependency() method, which
            // adds a (potentially unused) class reference to the constant
            // pool of the class.
            //
            // Previously, we added a dependency from every class in the
            // file, to every class in the file.  This introduced, in
            // total, a quadratic number of potentially bogus constant
            // pool entries.  This was bad.  Now we add our artificial
            // dependencies in such a way that the classes are connected
            // in a circle.  While single links is probably sufficient, the
            // code below adds double links just to be diligent.
            // (Fix for 4108286).
            //
            // Note that we don't chain in inner classes.  The links
            // between them and their outerclass should be sufficient
            // here.
            // (Fix for 4107960).
            //
            // The dependency code was previously in BatchParser.java.
            Enumeration e = p.classes.elements();

            // first will not be an inner class.
            ClassDefinition first = (ClassDefinition) e.nextElement();
            if (first.isInnerClass()) {
                throw new CompilerError("BatchEnvironment, first is inner");
            }

            ClassDefinition current = first;
            ClassDefinition next;
            while (e.hasMoreElements()) {
                next = (ClassDefinition) e.nextElement();
                // Don't chain in inner classes.
                if (next.isInnerClass()) {
                    continue;
                }
                current.addDependency(next.getClassDeclaration());
                next.addDependency(current.getClassDeclaration());
                current = next;
            }
            // Make a circle.  Don't bother to add a dependency if there
            // is only one class in the file.
            if (current != first) {
                current.addDependency(first.getClassDeclaration());
                first.addDependency(current.getClassDeclaration());
            }
        }

        if (tracing) dtExit("parseFile: SOURCE PARSED " + file);
    }

    /**
     * Load a binary file
     */
    BinaryClass loadFile(ClassFile file) throws IOException {
        long tm = System.currentTimeMillis();
        InputStream input = file.getInputStream();
        BinaryClass c = null;

        if (tracing) dtEnter("loadFile: LOADING CLASSFILE " + file);

        try {
            DataInputStream is =
                new DataInputStream(new BufferedInputStream(input));
            c = BinaryClass.load(new Environment(this, file), is,
                                 loadFileFlags());
        } catch (ClassFormatError e) {
            error(0, "class.format", file.getPath(), e.getMessage());
            if (tracing) dtExit("loadFile: CLASS FORMAT ERROR " + file);
            return null;
        } catch (java.io.EOFException e) {
            // If we get an EOF while processing a class file, then
            // it has been truncated.  We let other I/O errors pass
            // through.  Fix for 4088443.
            error(0, "truncated.class", file.getPath());
            return null;
        }

        input.close();
        if (verbose()) {
            tm = System.currentTimeMillis() - tm;
            output(Main.getText("benv.loaded_in", file.getPath(),
                                Long.toString(tm)));
        }

        if (tracing) dtExit("loadFile: CLASSFILE LOADED " + file);

        return c;
    }

    /**
     * Default flags for loadFile.  Subclasses may override this.
     */
    int loadFileFlags() {
        return 0;
    }

    /**
     * Load a binary class
     */
    boolean needsCompilation(Hashtable check, ClassDeclaration c) {
        switch (c.getStatus()) {

          case CS_UNDEFINED:
            if (tracing) dtEnter("needsCompilation: UNDEFINED " + c.getName());
            loadDefinition(c);
            return needsCompilation(check, c);

          case CS_UNDECIDED:
            if (tracing) dtEnter("needsCompilation: UNDECIDED " + c.getName());
            if (check.get(c) == null) {
                check.put(c, c);

                BinaryClass bin = (BinaryClass)c.getClassDefinition();
                for (Enumeration e = bin.getDependencies() ; e.hasMoreElements() ;) {
                    ClassDeclaration dep = (ClassDeclaration)e.nextElement();
                    if (needsCompilation(check, dep)) {
                        // It must be source, dependencies need compilation
                        c.setDefinition(bin, CS_SOURCE);
                        if (tracing) dtExit("needsCompilation: YES (source) " + c.getName());
                        return true;
                    }
                }
            }
            if (tracing) dtExit("needsCompilation: NO (undecided) " + c.getName());
            return false;

          case CS_BINARY:
            if (tracing) {
                dtEnter("needsCompilation: BINARY " + c.getName());
                dtExit("needsCompilation: NO (binary) " + c.getName());
            }
            return false;

        }

        if (tracing) dtExit("needsCompilation: YES " + c.getName());
        return true;
    }

    /**
     * Load the definition of a class
     * or at least determine how to load it.
     * The caller must repeat calls to this method
     * until it the state converges to CS_BINARY, CS_PARSED, or the like..
     * @see ClassDeclaration#getClassDefinition
     */
    public void loadDefinition(ClassDeclaration c) {
        if (tracing) dtEnter("loadDefinition: ENTER " +
                             c.getName() + ", status " + c.getStatus());
        switch (c.getStatus()) {
          case CS_UNDEFINED: {
            if (tracing)
                dtEvent("loadDefinition: STATUS IS UNDEFINED");
            Identifier nm = c.getName();
            Package pkg;
            try {
                pkg = getPackage(nm.getQualifier());
            } catch (IOException e) {
                // If we can't get at the package, then we'll just
                // have to set the class to be not found.
                c.setDefinition(null, CS_NOTFOUND);

                error(0, "io.exception", c);
                if (tracing)
                    dtExit("loadDefinition: IO EXCEPTION (package)");
                return;
            }
            ClassFile binfile = pkg.getBinaryFile(nm.getName());
            if (binfile == null) {
                // must be source, there is no binary
                c.setDefinition(null, CS_SOURCE);
                if (tracing)
                    dtExit("loadDefinition: MUST BE SOURCE (no binary) " +
                           c.getName());
                return;
            }

            ClassFile srcfile = pkg.getSourceFile(nm.getName());
            if (srcfile == null) {
                if (tracing)
                    dtEvent("loadDefinition: NO SOURCE " + c.getName());
                BinaryClass bc = null;
                try {
                    bc = loadFile(binfile);
                } catch (IOException e) {
                    // If we can't access the binary, set the class to
                    // be not found.  (bug id 4030497)
                    c.setDefinition(null, CS_NOTFOUND);

                    error(0, "io.exception", binfile);
                    if (tracing)
                        dtExit("loadDefinition: IO EXCEPTION (binary)");
                    return;
                }
                if ((bc != null) && !bc.getName().equals(nm)) {
                    error(0, "wrong.class", binfile.getPath(), c, bc);
                    bc = null;
                    if (tracing)
                        dtEvent("loadDefinition: WRONG CLASS (binary)");
                }
                if (bc == null) {
                    // no source nor binary found
                    c.setDefinition(null, CS_NOTFOUND);
                    if (tracing)
                        dtExit("loadDefinition: NOT FOUND (source or binary)");
                    return;
                }

                // Couldn't find the source, try the one mentioned in the binary
                if (bc.getSource() != null) {
                    srcfile = new ClassFile(new File((String)bc.getSource()));
                    // Look for the source file
                    srcfile = pkg.getSourceFile(srcfile.getName());
                    if ((srcfile != null) && srcfile.exists()) {
                        if (tracing)
                            dtEvent("loadDefinition: FILENAME IN BINARY " +
                                    srcfile);
                        if (srcfile.lastModified() > binfile.lastModified()) {
                            // must be source, it is newer than the binary
                            c.setDefinition(bc, CS_SOURCE);
                            if (tracing)
                                dtEvent("loadDefinition: SOURCE IS NEWER " +
                                        srcfile);
                            bc.loadNested(this);
                            if (tracing)
                                dtExit("loadDefinition: MUST BE SOURCE " +
                                       c.getName());
                            return;
                        }
                        if (dependencies()) {
                            c.setDefinition(bc, CS_UNDECIDED);
                            if (tracing)
                                dtEvent("loadDefinition: UNDECIDED " +
                                        c.getName());
                        } else {
                            c.setDefinition(bc, CS_BINARY);
                            if (tracing)
                                dtEvent("loadDefinition: MUST BE BINARY " +
                                        c.getName());
                        }
                        bc.loadNested(this);
                        if (tracing)
                            dtExit("loadDefinition: EXIT " +
                                   c.getName() + ", status " + c.getStatus());
                        return;
                    }
                }

                // It must be binary, there is no source
                c.setDefinition(bc, CS_BINARY);
                if (tracing)
                    dtEvent("loadDefinition: MUST BE BINARY (no source) " +
                                     c.getName());
                bc.loadNested(this);
                if (tracing)
                    dtExit("loadDefinition: EXIT " +
                           c.getName() + ", status " + c.getStatus());
                return;
            }
            BinaryClass bc = null;
            try {
                if (srcfile.lastModified() > binfile.lastModified()) {
                    // must be source, it is newer than the binary
                    c.setDefinition(null, CS_SOURCE);
                    if (tracing)
                        dtEvent("loadDefinition: MUST BE SOURCE (younger than binary) " +
                                c.getName());
                    return;
                }
                bc = loadFile(binfile);
            } catch (IOException e) {
                error(0, "io.exception", binfile);
                if (tracing)
                    dtEvent("loadDefinition: IO EXCEPTION (binary)");
            }
            if ((bc != null) && !bc.getName().equals(nm)) {
                error(0, "wrong.class", binfile.getPath(), c, bc);
                bc = null;
                if (tracing)
                    dtEvent("loadDefinition: WRONG CLASS (binary)");
            }
            if (bc != null) {
                Identifier name = bc.getName();
                if (name.equals(c.getName())) {
                    if (dependencies()) {
                        c.setDefinition(bc, CS_UNDECIDED);
                        if (tracing)
                            dtEvent("loadDefinition: UNDECIDED " + name);
                    } else {
                        c.setDefinition(bc, CS_BINARY);
                        if (tracing)
                            dtEvent("loadDefinition: MUST BE BINARY " + name);
                    }
                } else {
                    c.setDefinition(null, CS_NOTFOUND);
                    if (tracing)
                        dtEvent("loadDefinition: NOT FOUND (source or binary)");
                    if (dependencies()) {
                        getClassDeclaration(name).setDefinition(bc, CS_UNDECIDED);
                        if (tracing)
                            dtEvent("loadDefinition: UNDECIDED " + name);
                    } else {
                        getClassDeclaration(name).setDefinition(bc, CS_BINARY);
                        if (tracing)
                            dtEvent("loadDefinition: MUST BE BINARY " + name);
                    }
                }
            } else {
                c.setDefinition(null, CS_NOTFOUND);
                if (tracing)
                    dtEvent("loadDefinition: NOT FOUND (source or binary)");
            }
            if (bc != null && bc == c.getClassDefinition())
                bc.loadNested(this);
            if (tracing) dtExit("loadDefinition: EXIT " +
                                c.getName() + ", status " + c.getStatus());
            return;
          }

          case CS_UNDECIDED: {
            if (tracing) dtEvent("loadDefinition: STATUS IS UNDECIDED");
            Hashtable tab = new Hashtable();
            if (!needsCompilation(tab, c)) {
                // All undecided classes that this class depends on must be binary
                for (Enumeration e = tab.keys() ; e.hasMoreElements() ; ) {
                    ClassDeclaration dep = (ClassDeclaration)e.nextElement();
                    if (dep.getStatus() == CS_UNDECIDED) {
                        // must be binary, dependencies need compilation
                        dep.setDefinition(dep.getClassDefinition(), CS_BINARY);
                        if (tracing)
                            dtEvent("loadDefinition: MUST BE BINARY " + dep);
                    }
                }
            }
            if (tracing) dtExit("loadDefinition: EXIT " +
                                c.getName() + ", status " + c.getStatus());
            return;
          }

          case CS_SOURCE: {
            if (tracing) dtEvent("loadDefinition: STATUS IS SOURCE");
            ClassFile srcfile = null;
            Package pkg = null;
            if (c.getClassDefinition() != null) {
                // Use the source file name from the binary class file
                try {
                    pkg = getPackage(c.getName().getQualifier());
                    srcfile = pkg.getSourceFile((String)c.getClassDefinition().getSource());
                } catch (IOException e) {
                    error(0, "io.exception", c);
                    if (tracing)
                        dtEvent("loadDefinition: IO EXCEPTION (package)");
                }
                if (srcfile == null) {
                    String fn = (String)c.getClassDefinition().getSource();
                    srcfile = new ClassFile(new File(fn));
                }
            } else {
                // Get a source file name from the package
                Identifier nm = c.getName();
                try {
                    pkg = getPackage(nm.getQualifier());
                    srcfile = pkg.getSourceFile(nm.getName());
                } catch (IOException e)  {
                    error(0, "io.exception", c);
                    if (tracing)
                        dtEvent("loadDefinition: IO EXCEPTION (package)");
                }
                if (srcfile == null) {
                    // not found, there is no source
                    c.setDefinition(null, CS_NOTFOUND);
                    if (tracing)
                        dtExit("loadDefinition: SOURCE NOT FOUND " +
                               c.getName() + ", status " + c.getStatus());
                    return;
                }
            }
            try {
                parseFile(srcfile);
            } catch (FileNotFoundException e) {
                error(0, "io.exception", srcfile);
                if (tracing) dtEvent("loadDefinition: IO EXCEPTION (source)");
            }
            if ((c.getClassDefinition() == null) || (c.getStatus() == CS_SOURCE)) {
                // not found after parsing the file
                error(0, "wrong.source", srcfile.getPath(), c, pkg);
                c.setDefinition(null, CS_NOTFOUND);
                if (tracing)
                    dtEvent("loadDefinition: WRONG CLASS (source) " +
                            c.getName());
            }
            if (tracing) dtExit("loadDefinition: EXIT " +
                                c.getName() + ", status " + c.getStatus());
            return;
          }
        }
        if (tracing) dtExit("loadDefinition: EXIT " +
                            c.getName() + ", status " + c.getStatus());
    }

    /**
     * Create a new class.
     */
    public ClassDefinition makeClassDefinition(Environment toplevelEnv,
                                               long where,
                                               IdentifierToken name,
                                               String doc, int modifiers,
                                               IdentifierToken superClass,
                                               IdentifierToken interfaces[],
                                               ClassDefinition outerClass) {

        Identifier nm = name.getName();
        long nmpos = name.getWhere();

        Identifier pkgNm;
        String mangledName = null;
        ClassDefinition localContextClass = null;

        // Provide name for a local class.  This used to be set after
        // the class was created, but it is needed for checking within
        // the class constructor.
        // NOTE: It seems that we could always provide the simple name,
        // and thereby avoid the test in 'ClassDefinition.getLocalName()'
        // for the definedness of the local name.  There, if the local
        // name is not set, a simple name is extracted from the result of
        // 'getName()'.  That name can potentially change, however, as
        // it is ultimately derived from 'ClassType.className', which is
        // set by 'Type.changeClassName'.  Better leave this alone...
        Identifier localName = null;

        if (nm.isQualified() || nm.isInner()) {
            pkgNm = nm;
        } else if ((modifiers & (M_LOCAL | M_ANONYMOUS)) != 0) {
            // Inaccessible class.  Create a name of the form
            // 'PackageMember.N$localName' or 'PackageMember.N'.
            // Note that the '.' will be converted later to a '$'.
            //   pkgNm = generateName(outerClass, nm);
            localContextClass = outerClass.getTopClass();
            // Always use the smallest number in generating the name that
            // renders the complete name unique within the top-level class.
            // This is required to make the names more predictable, as part
            // of a serialization-related workaround, and satisfies an obscure
            // requirement that the name of a local class be of the form
            // 'PackageMember$1$localName' when this name is unique.
            for (int i = 1 ; ; i++) {
                mangledName = i + (nm.equals(idNull) ? "" : SIG_INNERCLASS + nm);
                if (localContextClass.getLocalClass(mangledName) == null) {
                    break;
                }
            }
            Identifier outerNm = localContextClass.getName();
            pkgNm = Identifier.lookupInner(outerNm, Identifier.lookup(mangledName));
            //System.out.println("LOCAL CLASS: " + pkgNm + " IN " + localContextClass);
            if ((modifiers & M_ANONYMOUS) != 0) {
                localName = idNull;
            } else {
                // Local class has a locally-scoped name which is independent of pkgNm.
                localName = nm;
            }
        } else if (outerClass != null) {
            // Accessible inner class.  Qualify name with surrounding class name.
            pkgNm = Identifier.lookupInner(outerClass.getName(), nm);
        } else {
            pkgNm = nm;
        }

        // Find the class
        ClassDeclaration c = toplevelEnv.getClassDeclaration(pkgNm);

        // Make sure this is the first definition
        if (c.isDefined()) {
            toplevelEnv.error(nmpos, "class.multidef",
                              c.getName(), c.getClassDefinition().getSource());
            // Don't mess with the existing class declarations with same name
            c = new ClassDeclaration (pkgNm);
        }

        if (superClass == null && !pkgNm.equals(idJavaLangObject)) {
            superClass = new IdentifierToken(idJavaLangObject);
        }

        ClassDefinition sourceClass =
            new SourceClass(toplevelEnv, where, c, doc,
                            modifiers, superClass, interfaces,
                            (SourceClass) outerClass, localName);

        if (outerClass != null) {
            // It is a member of its enclosing class.
            outerClass.addMember(toplevelEnv, new SourceMember(sourceClass));
            // Record local (or anonymous) class in the class whose name will
            // serve as the prefix of the local class name.  This is necessary
            // so that the class may be retrieved from its name, which does not
            // fully represent the class nesting structure.
            // See 'ClassDefinition.getClassDefinition'.
            // This is part of a fix for bugid 4054523 and 4030421.
            if ((modifiers & (M_LOCAL | M_ANONYMOUS)) != 0) {
                localContextClass.addLocalClass(sourceClass, mangledName);
            }
        }

        // The local name of an anonymous or local class used to be set here
        // with a call to 'setLocalName'.  This has been moved to the constructor
        // for 'SourceClass', which now takes a 'localName' argument.

        return sourceClass;
    }

    /**
     * Create a new field.
     */
    public MemberDefinition makeMemberDefinition(Environment origEnv, long where,
                                               ClassDefinition clazz,
                                               String doc, int modifiers,
                                               Type type, Identifier name,
                                               IdentifierToken argNames[],
                                               IdentifierToken expIds[],
                                               Object value) {
        if (tracing) dtEvent("makeMemberDefinition: " + name + " IN " + clazz);
        Vector v = null;
        if (argNames != null) {
            v = new Vector(argNames.length);
            for (int i = 0 ; i < argNames.length ; i++) {
                v.addElement(argNames[i]);
            }
        }
        SourceMember f = new SourceMember(where, clazz, doc, modifiers,
                                        type, name, v, expIds, (Node)value);
        clazz.addMember(origEnv, f);
        return f;
    }

    /**
     * Release resources in classpath.
     */
    public void shutdown() {
        try {
            if (sourcePath != null) {
                sourcePath.close();
            }
            if (binaryPath != null && binaryPath != sourcePath) {
                binaryPath.close();
            }
        } catch (IOException ee) {
            output(Main.getText("benv.failed_to_close_class_path",
                                ee.toString()));
        }
        sourcePath = null;
        binaryPath = null;

        super.shutdown();
    }

    /**
     * Error String
     */
    public
    String errorString(String err, Object arg1, Object arg2, Object arg3) {
        String key = null;

        if(err.startsWith("warn."))
            key = "javac.err." + err.substring(5);
        else
            key = "javac.err." + err;

        return Main.getText(key,
                            arg1 != null ? arg1.toString() : null,
                            arg2 != null ? arg2.toString() : null,
                            arg3 != null ? arg3.toString() : null);
    }

    /**
     * The filename where the last errors have occurred
     */
    String errorFileName;

    /**
     * List of outstanding error messages
     */
    ErrorMessage errors;

    /**
     * Insert an error message in the list of outstanding error messages.
     * The list is sorted on input position and contains no duplicates.
     * The return value indicates whether or not the message was
     * actually inserted.
     *
     * The method flushErrors() used to check for duplicate error messages.
     * It would only detect duplicates if they were contiguous.  Removing
     * non-contiguous duplicate error messages is slightly less complicated
     * at insertion time, so the functionality was moved here.  This also
     * saves a miniscule number of allocations.
     */
    protected
    boolean insertError(long where, String message) {
        //output("ERR = " + message);

        if (errors == null
            ||  errors.where > where) {
            // If the list is empty, or the error comes before any other
            // errors, insert it at the beginning of the list.
            ErrorMessage newMsg = new ErrorMessage(where, message);
            newMsg.next = errors;
            errors = newMsg;

        } else if (errors.where == where
                   && errors.message.equals(message)) {
            // The new message is an exact duplicate of the first message
            // in the list.  Don't insert it.
            return false;

        } else {
            // Okay, we know that the error doesn't come first.  Walk
            // the list until we find the right position for insertion.
            ErrorMessage current = errors;
            ErrorMessage next;

            while ((next = current.next) != null
                   && next.where < where) {
                current = next;
            }

            // Now walk over any errors with the same location, looking
            // for duplicates.  If we find a duplicate, don't insert the
            // error.
            while ((next = current.next) != null
                   && next.where == where) {
                if (next.message.equals(message)) {
                    // We have found an exact duplicate.  Don't bother to
                    // insert the error.
                    return false;
                }
                current = next;
            }

            // Now insert after current.
            ErrorMessage newMsg = new ErrorMessage(where, message);
            newMsg.next = current.next;
            current.next = newMsg;
        }

        // Indicate that the insertion occurred.
        return true;
    }

    private int errorsPushed;

    /**
     * Maximum number of errors to print.
     */
    public int errorLimit = 100;

    private boolean hitErrorLimit;

    /**
     * Flush outstanding errors
     */

        public void pushError(String errorFileName, int line, String message,
                                    String referenceText, String referenceTextPointer) {
                int limit = errorLimit + nwarnings;
                if (++errorsPushed >= limit && errorLimit >= 0) {
                    if (!hitErrorLimit) {
                        hitErrorLimit = true;
                        output(errorString("too.many.errors",
                                           new Integer(errorLimit),null,null));
                    }
                    return;
                }
                if (errorFileName.endsWith(".java")) {
                    output(errorFileName + ":" + line + ": " + message);
                    output(referenceText);
                    output(referenceTextPointer);
                } else {
                    // It wasn't really a source file (probably an error or
                    // warning because of a malformed or badly versioned
                    // class file.
                    output(errorFileName + ": " + message);
                }
        }

    public void flushErrors() {
        if (errors == null) {
            return;
        }

        boolean inputAvail = false;
        // Read the file
        char data[] = null;
        int dataLength = 0;
        // A malformed file encoding could cause a CharConversionException.
        // If something bad happens while trying to find the source file,
        // don't bother trying to show lines.
        try {
            FileInputStream in = new FileInputStream(errorFileName);
            data = new char[in.available()];
            InputStreamReader reader =
                (getCharacterEncoding() != null ?
                 new InputStreamReader(in, getCharacterEncoding()) :
                 new InputStreamReader(in));
            dataLength = reader.read(data);
            reader.close();
            inputAvail = true;
        } catch(IOException e) {
            // inputAvail will not be set
        }

        // Report the errors
        for (ErrorMessage msg = errors ; msg != null ; msg = msg.next) {
            // There used to be code here which checked
            // for duplicate error messages.  This functionality
            // has been moved to the method insertError().  See
            // the comments on that method for more information.

            int ln = (int) (msg.where >>> WHEREOFFSETBITS);
            int off = (int) (msg.where & ((1L << WHEREOFFSETBITS) - 1));
            if (off > dataLength)  off = dataLength;

            String referenceString = "";
            String markerString = "";
            if(inputAvail) {
                int i, j;
                for (i = off ; (i > 0) && (data[i - 1] != '\n') && (data[i - 1] != '\r') ; i--);
                for (j = off ; (j < dataLength) && (data[j] != '\n') && (data[j] != '\r') ; j++);
                referenceString = new String(data, i, j - i);

                char strdata[] = new char[(off - i) + 1];
                for (j = i ; j < off ; j++) {
                    strdata[j-i] = (data[j] == '\t') ? '\t' : ' ';
                }
                strdata[off-i] = '^';
                markerString = new String(strdata);
            }

            errorConsumer.pushError(errorFileName, ln, msg.message,
                                        referenceString, markerString);
        }
        errors = null;
    }

    /**
     * Report error
     */
    public
    void reportError(Object src, long where, String err, String msg) {
        if (src == null) {
            if (errorFileName != null) {
                flushErrors();
                errorFileName = null;
            }
            if (err.startsWith("warn.")) {
                if (warnings()) {
                    nwarnings++;
                    output(msg);
                }
                return;
            }
            output("error: " + msg);
            nerrors++;
            flags |= F_ERRORSREPORTED;

        } else if (src instanceof String) {
            String fileName = (String)src;

            // Flush errors if we've moved on to a new file.
            if (!fileName.equals(errorFileName)) {
                flushErrors();
                errorFileName = fileName;
            }

            // Classify `err' as a warning, deprecation warning, or
            // error message.  Proceed accordingly.
            if (err.startsWith("warn.")) {
                if (err.indexOf("is.deprecated") >= 0) {
                    // This is a deprecation warning.  Add `src' to the
                    // list of files with deprecation warnings.
                    if (!deprecationFiles.contains(src)) {
                        deprecationFiles.addElement(src);
                    }

                    // If we are reporting deprecations, try to add it
                    // to our list.  Otherwise, just increment the
                    // deprecation count.
                    if (deprecation()) {
                        if (insertError(where, msg)) {
                            ndeprecations++;
                        }
                    } else {
                        ndeprecations++;
                    }
                } else {
                    // This is a regular warning.  If we are reporting
                    // warnings, try to add it to the list.  Otherwise, just
                    // increment the warning count.
                    if (warnings()) {
                        if (insertError(where, msg)) {
                            nwarnings++;
                        }
                    } else {
                        nwarnings++;
                    }
                }
            } else {
                // This is an error.  Try to add it to the list of errors.
                // If it isn't a duplicate, increment our error count.
                if (insertError(where, msg)) {
                    nerrors++;
                    flags |= F_ERRORSREPORTED;
                }
            }
        } else if (src instanceof ClassFile) {
            reportError(((ClassFile)src).getPath(), where, err, msg);

        } else if (src instanceof Identifier) {
            reportError(src.toString(), where, err, msg);

        } else if (src instanceof ClassDeclaration) {
            try {
                reportError(((ClassDeclaration)src).getClassDefinition(this), where, err, msg);
            } catch (ClassNotFound e) {
                reportError(((ClassDeclaration)src).getName(), where, err, msg);
            }
        } else if (src instanceof ClassDefinition) {
            ClassDefinition c = (ClassDefinition)src;
            if (!err.startsWith("warn.")) {
                c.setError();
            }
            reportError(c.getSource(), where, err, msg);

        } else if (src instanceof MemberDefinition) {
            reportError(((MemberDefinition)src).getClassDeclaration(), where, err, msg);

        } else {
            output(src + ":error=" + err + ":" + msg);
        }
    }

    /**
     * Issue an error
     */
    public void error(Object source, long where, String err, Object arg1, Object arg2, Object arg3) {
        if (errorsPushed >= errorLimit + nwarnings) {
            // Don't bother to queue any more errors if they won't get printed.
            return;
        }
        if (System.getProperty("javac.dump.stack") != null) {
            output("javac.err."+err+": "+errorString(err, arg1, arg2, arg3));
            new Exception("Stack trace").printStackTrace(new PrintStream(out));
        }
        reportError(source, where, err, errorString(err, arg1, arg2, arg3));
    }

    /**
     * Output a string. This can either be an error message or something
     * for debugging.
     */
    public void output(String msg) {
        PrintStream out =
            this.out instanceof PrintStream ? (PrintStream)this.out
                                            : new PrintStream(this.out, true);
        out.println(msg);
    }
}
