/*
 * Copyright 1994-2003 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.java;

import java.util.Stack;
import java.io.IOException;
import sun.tools.tree.Context;
//JCOV
import java.io.File;
//end JCOV

/**
 * This class defines the environment for a compilation.
 * It is used to load classes, resolve class names and
 * report errors. It is an abstract class, a subclass
 * must define implementations for some of the functions.<p>
 *
 * An environment has a source object associated with it.
 * This is the thing against which errors are reported, it
 * is usually a file name, a field or a class.<p>
 *
 * Environments can be nested to change the source object.<p>
 *
 * 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.
 *
 * @author      Arthur van Hoff
 */

public class Environment implements Constants {
    /**
     * The actual environment to which everything is forwarded.
     */
    Environment env;

    /**
     * External character encoding name
     */
    String encoding;

    /**
     * The object that is currently being parsed/compiled.
     * It is either a file name (String) or a field (MemberDefinition)
     * or a class (ClassDeclaration or ClassDefinition).
     */
    Object source;

    public Environment(Environment env, Object source) {
        if (env != null && env.env != null && env.getClass() == this.getClass())
            env = env.env;      // a small optimization
        this.env = env;
        this.source = source;
    }
    public Environment() {
        this(null, null);
    }

    /**
     * Tells whether an Identifier refers to a package which should be
     * exempt from the "exists" check in Imports#resolve().
     */
    public boolean isExemptPackage(Identifier id) {
        return env.isExemptPackage(id);
    }

    /**
     * Return a class declaration given a fully qualified class name.
     */
    public ClassDeclaration getClassDeclaration(Identifier nm) {
        return env.getClassDeclaration(nm);
    }

    /**
     * Return a class definition given a fully qualified class name.
     * <p>
     * Should be called only with 'internal' class names, i.e., the result
     * of a call to 'resolveName' or a synthetic class name.
     */
    public final ClassDefinition getClassDefinition(Identifier nm) throws ClassNotFound {
        if (nm.isInner()) {
            ClassDefinition c = getClassDefinition(nm.getTopName());
            Identifier tail = nm.getFlatName();
        walkTail:
            while (tail.isQualified()) {
                tail = tail.getTail();
                Identifier head = tail.getHead();
                //System.out.println("CLASS: " + c + " HEAD: " + head + " TAIL: " + tail);
                String hname = head.toString();
                // If the name is of the form 'ClassName.N$localName', where N is
                // a number, the field 'N$localName' may not necessarily be a member
                // of the class named by 'ClassName', but might be a member of some
                // inaccessible class contained within it.  We use 'getLocalClass'
                // to do the lookup in this case.  This is part of a fix for bugid
                // 4054523 and 4030421.  See also 'BatchEnvironment.makeClassDefinition'.
                // This should also work for anonymous class names of the form
                // 'ClassName.N'.  Note that the '.' qualifications get converted to
                // '$' characters when determining the external name of the class and
                // the name of the class file.
                if (hname.length() > 0
                    && Character.isDigit(hname.charAt(0))) {
                    ClassDefinition localClass = c.getLocalClass(hname);
                    if (localClass != null) {
                        c = localClass;
                        continue walkTail;
                    }
                } else {
                    for (MemberDefinition f = c.getFirstMatch(head);
                         f != null; f = f.getNextMatch()) {
                        if (f.isInnerClass()) {
                            c = f.getInnerClass();
                            continue walkTail;
                        }
                    }
                }
                throw new ClassNotFound(Identifier.lookupInner(c.getName(), head));
            }
            //System.out.println("FOUND " + c + " FOR " + nm);
            return c;
        }
        return getClassDeclaration(nm).getClassDefinition(this);
    }


    /**
     * Return a class declaration given a type. Only works for
     * class types.
     */
    public ClassDeclaration getClassDeclaration(Type t) {
        return getClassDeclaration(t.getClassName());
    }

    /**
     * Return a class definition given a type. Only works for
     * class types.
     */
    public final ClassDefinition getClassDefinition(Type t) throws ClassNotFound {
        return getClassDefinition(t.getClassName());
    }

    /**
     * Check if a class exists (without actually loading it).
     * (Since inner classes cannot in general be examined without
     * loading source, this method does not accept inner names.)
     */
    public boolean classExists(Identifier nm) {
        return env.classExists(nm);
    }

    public final boolean classExists(Type t) {
        return !t.isType(TC_CLASS) || classExists(t.getClassName());
    }

    /**
     * Get the package path for a package
     */
    public Package getPackage(Identifier pkg) throws IOException {
        return env.getPackage(pkg);
    }

    /**
     * Load the definition of a class.
     */
    public void loadDefinition(ClassDeclaration c) {
        env.loadDefinition(c);
    }

    /**
     * Return the source of the environment (ie: the thing being compiled/parsed).
     */
    public final Object getSource() {
        return source;
    }

    /**
     * Resolve a type. Make sure that all the classes referred to by
     * the type have a definition.  Report errors.  Return true if
     * the type is well-formed.  Presently used for types appearing
     * in member declarations, which represent named types internally as
     * qualified identifiers.  Type names appearing in local variable
     * declarations and within expressions are represented as identifier
     * or field expressions, and are resolved by 'toType', which delegates
     * handling of the non-inner portion of the name to this method.
     * <p>
     * In 'toType', the various stages of qualification are represented by
     * separate AST nodes.  Here, we are given a single identifier which
     * contains the entire qualification structure.  It is not possible in
     * general to set the error location to the exact position of a component
     * that is in error, so an error message must refer to the entire qualified
     * name.  An attempt to keep track of the string length of the components of
     * the name and to offset the location accordingly fails because the initial
     * prefix of the name may have been rewritten by an earlier call to
     * 'resolveName'.  See 'SourceMember.resolveTypeStructure'.  The situation
     * is actually even worse than this, because only a single location is
     * passed in for an entire declaration, which may contain many type names.
     * All error messages are thus poorly localized.  These checks should be
     * done while traversing the parse tree for the type, not the type descriptor.
     * <p>
     * DESIGN NOTE:
     * As far as I can tell, the two-stage resolution of names represented in
     * string form is an artifact of the late implementation of inner classes
     * and the use of mangled names internally within the compiler.  All
     * qualified names should have their hiearchical structure made explicit
     * in the parse tree at the phase at which they are presented for static
     * semantic checking.  This would affect class names appearing in 'extends',
     * 'implements', and 'throws' clauses, as well as in member declarations.
     */
    public boolean resolve(long where, ClassDefinition c, Type t) {
        switch (t.getTypeCode()) {
          case TC_CLASS: {
            ClassDefinition def;
            try {
                Identifier nm = t.getClassName();
                if (!nm.isQualified() && !nm.isInner() && !classExists(nm)) {
                    resolve(nm);        // elicit complaints about ambiguity
                }
                def = getQualifiedClassDefinition(where, nm, c, false);
                if (!c.canAccess(this, def.getClassDeclaration())) {
                    // Reported error location may be imprecise
                    // if the name is qualified.
                    error(where, "cant.access.class", def);
                    return true; // return false later
                }
                def.noteUsedBy(c, where, env);
            } catch (AmbiguousClass ee) {
                error(where, "ambig.class", ee.name1, ee.name2);
                return false;
            } catch (ClassNotFound e) {
                // For now, report "class.and.package" only when the code
                // is going to fail anyway.
                try {
                    if (e.name.isInner() &&
                            getPackage(e.name.getTopName()).exists()) {
                        env.error(where, "class.and.package",
                                  e.name.getTopName());
                    }
                } catch (IOException ee) {
                    env.error(where, "io.exception", "package check");
                }
                // This error message is also emitted for 'new' expressions.
                // error(where, "class.not.found", e.name, "declaration");
                error(where, "class.not.found.no.context", e.name);
                return false;
            }
            return true;
          }

          case TC_ARRAY:
            return resolve(where, c, t.getElementType());

          case TC_METHOD:
            boolean ok = resolve(where, c, t.getReturnType());
            Type args[] = t.getArgumentTypes();
            for (int i = args.length ; i-- > 0 ; ) {
                ok &= resolve(where, c, args[i]);
            }
            return ok;
        }
        return true;
    }

    /**
     * Given its fully-qualified name, verify that a class is defined and accessible.
     * Used to check components of qualified names in contexts where a class is expected.
     * Like 'resolve', but is given a single type name, not a type descriptor.
     */
    public boolean resolveByName(long where, ClassDefinition c, Identifier nm) {
        return resolveByName(where, c, nm, false);
    }

    public boolean resolveExtendsByName(long where, ClassDefinition c, Identifier nm) {
        return resolveByName(where, c, nm, true);
    }

    private boolean resolveByName(long where, ClassDefinition c,
                                 Identifier nm, boolean isExtends) {
        ClassDefinition def;
        try {
            if (!nm.isQualified() && !nm.isInner() && !classExists(nm)) {
                resolve(nm);    // elicit complaints about ambiguity
            }
            def = getQualifiedClassDefinition(where, nm, c, isExtends);
            ClassDeclaration decl = def.getClassDeclaration();
            if (!((!isExtends && c.canAccess(this, decl))
                  ||
                  (isExtends && c.extendsCanAccess(this, decl)))) {
                error(where, "cant.access.class", def);
                return true; // return false later
            }
        } catch (AmbiguousClass ee) {
            error(where, "ambig.class", ee.name1, ee.name2);
            return false;
        } catch (ClassNotFound e) {
            // For now, report "class.and.package" only when the code
            // is going to fail anyway.
            try {
                if (e.name.isInner() &&
                    getPackage(e.name.getTopName()).exists()) {
                    env.error(where, "class.and.package",
                              e.name.getTopName());
                }
            } catch (IOException ee) {
                env.error(where, "io.exception", "package check");
            }
            error(where, "class.not.found", e.name, "type name");
            return false;
        }
        return true;
    }

    /**
     * Like 'getClassDefinition(env)', but check access on each component.
     * Currently called only by 'resolve' above.  It is doubtful that calls
     * to 'getClassDefinition(env)' are appropriate now.
     */
    public final ClassDefinition
    getQualifiedClassDefinition(long where,
                                Identifier nm,
                                ClassDefinition ctxClass,
                                boolean isExtends) throws ClassNotFound {
        if (nm.isInner()) {
            ClassDefinition c = getClassDefinition(nm.getTopName());
            Identifier tail = nm.getFlatName();
        walkTail:
            while (tail.isQualified()) {
                tail = tail.getTail();
                Identifier head = tail.getHead();
                // System.out.println("CLASS: " + c + " HEAD: " + head + " TAIL: " + tail);
                String hname = head.toString();
                // Handle synthesized names of local and anonymous classes.
                // See 'getClassDefinition(env)' above.
                if (hname.length() > 0
                    && Character.isDigit(hname.charAt(0))) {
                    ClassDefinition localClass = c.getLocalClass(hname);
                    if (localClass != null) {
                        c = localClass;
                        continue walkTail;
                    }
                } else {
                    for (MemberDefinition f = c.getFirstMatch(head);
                         f != null; f = f.getNextMatch()) {
                        if (f.isInnerClass()) {
                            ClassDeclaration rdecl = c.getClassDeclaration();
                            c = f.getInnerClass();
                            ClassDeclaration fdecl = c.getClassDeclaration();
                            // This check is presumably applicable even if the
                            // original source-code name (expanded by 'resolveNames')
                            // was a simple, unqualified name.  Hopefully, JLS 2e
                            // will clarify the matter.
                            if ((!isExtends
                                 && !ctxClass.canAccess(env, fdecl))
                                ||
                                (isExtends
                                 && !ctxClass.extendsCanAccess(env, fdecl))) {
                                // Reported error location is imprecise.
                                env.error(where, "no.type.access", head, rdecl, ctxClass);
                            }
                            // The JLS 6.6.2 restrictions on access to protected members
                            // depend in an essential way upon the syntactic form of the name.
                            // Since the compiler has previously expanded the class names
                            // here into fully-qualified form ('resolveNames'), this check
                            // cannot be performed here.  Unfortunately, the original names
                            // are clobbered during 'basicCheck', which is also the phase that
                            // resolves the inheritance structure, required to implement the
                            // access restrictions.  Pending a large-scale revision of the
                            // name-resolution machinery, we forgo this check, with the result
                            // that the JLS 6.6.2 restrictions are not enforced for some cases
                            // of qualified access to inner classes.  Some qualified names are
                            // resolved elsewhere via a different mechanism, and will be
                            // treated correctly -- see 'FieldExpression.checkCommon'.
                            /*---------------------------------------*
                            if (f.isProtected()) {
                                Type rty = Type.tClass(rdecl.getName()); // hack
                                if (!ctxClass.protectedAccess(env, f, rty)) {
                                    // Reported error location is imprecise.
                                    env.error(where, "invalid.protected.type.use",
                                              head, ctxClass, rty);
                                }
                            }
                            *---------------------------------------*/
                            continue walkTail;
                        }
                    }
                }
                throw new ClassNotFound(Identifier.lookupInner(c.getName(), head));
            }
            //System.out.println("FOUND " + c + " FOR " + nm);
            return c;
        }
        return getClassDeclaration(nm).getClassDefinition(this);
    }

    /**
     * Resolve the names within a type, returning the adjusted type.
     * Adjust class names to reflect scoping.
     * Do not report errors.
     * <p>
     * NOTE: It would be convenient to check for errors here, such as
     * verifying that each component of a qualified name exists and is
     * accessible.  Why must this be done in a separate phase?
     * <p>
     * If the 'synth' argument is true, indicating that the member whose
     * type is being resolved is synthetic, names are resolved with respect
     * to the package scope.  (Fix for 4097882)
     */
    public Type resolveNames(ClassDefinition c, Type t, boolean synth) {
        if (tracing) dtEvent("Environment.resolveNames: " + c + ", " + t);
        switch (t.getTypeCode()) {
          case TC_CLASS: {
            Identifier name = t.getClassName();
            Identifier rname;
            if (synth) {
                rname = resolvePackageQualifiedName(name);
            } else {
                rname = c.resolveName(this, name);
            }
            if (name != rname) {
                t = Type.tClass(rname);
            }
            break;
          }

          case TC_ARRAY:
            t = Type.tArray(resolveNames(c, t.getElementType(), synth));
            break;

          case TC_METHOD: {
            Type ret = t.getReturnType();
            Type rret = resolveNames(c, ret, synth);
            Type args[] = t.getArgumentTypes();
            Type rargs[] = new Type[args.length];
            boolean changed = (ret != rret);
            for (int i = args.length ; i-- > 0 ; ) {
                Type arg = args[i];
                Type rarg = resolveNames(c, arg, synth);
                rargs[i] = rarg;
                if (arg != rarg) {
                    changed = true;
                }
            }
            if (changed) {
                t = Type.tMethod(rret, rargs);
            }
            break;
          }
        }
        return t;
    }

    /**
     * Resolve a class name, using only package and import directives.
     * Report no errors.
     * <p>
     */
    public Identifier resolveName(Identifier name) {
        // This logic is pretty exactly parallel to that of
        // ClassDefinition.resolveName().
        if (name.isQualified()) {
            // Try to resolve the first identifier component,
            // because inner class names take precedence over
            // package prefixes.  (Cf. ClassDefinition.resolveName.)
            Identifier rhead = resolveName(name.getHead());

            if (rhead.hasAmbigPrefix()) {
                // The first identifier component refers to an
                // ambiguous class.  Limp on.  We throw away the
                // rest of the classname as it is irrelevant.
                // (part of solution for 4059855).
                return rhead;
            }

            if (!this.classExists(rhead)) {
                return this.resolvePackageQualifiedName(name);
            }
            try {
                return this.getClassDefinition(rhead).
                    resolveInnerClass(this, name.getTail());
            } catch (ClassNotFound ee) {
                // return partially-resolved name someone else can fail on
                return Identifier.lookupInner(rhead, name.getTail());
            }
        }
        try {
            return resolve(name);
        } catch (AmbiguousClass ee) {
            // Don't force a resolution of the name if it is ambiguous.
            // Forcing the resolution would tack the current package
            // name onto the front of the class, which would be wrong.
            // Instead, mark the name as ambiguous and let a later stage
            // find the error by calling env.resolve(name).
            // (part of solution for 4059855).

            if (name.hasAmbigPrefix()) {
                return name;
            } else {
                return name.addAmbigPrefix();
            }
        } catch (ClassNotFound ee) {
            // last chance to make something halfway sensible
            Imports imports = getImports();
            if (imports != null)
                return imports.forceResolve(this, name);
        }
        return name;
    }

    /**
     * Discover if name consists of a package prefix, followed by the
     * name of a class (that actually exists), followed possibly by
     * some inner class names.  If we can't find a class that exists,
     * return the name unchanged.
     * <p>
     * This routine is used after a class name fails to
     * be resolved by means of imports or inner classes.
     * However, import processing uses this routine directly,
     * since import names must be exactly qualified to start with.
     */
    public final Identifier resolvePackageQualifiedName(Identifier name) {
        Identifier tail = null;
        for (;;) {
            if (classExists(name)) {
                break;
            }
            if (!name.isQualified()) {
                name = (tail == null) ? name : Identifier.lookup(name, tail);
                tail = null;
                break;
            }
            Identifier nm = name.getName();
            tail = (tail == null)? nm: Identifier.lookup(nm, tail);
            name = name.getQualifier();
        }
        if (tail != null)
            name = Identifier.lookupInner(name, tail);
        return name;
    }

    /**
     * Resolve a class name, using only package and import directives.
     */
    public Identifier resolve(Identifier nm) throws ClassNotFound {
        if (env == null)  return nm;    // a pretty useless no-op
        return env.resolve(nm);
    }

    /**
     * Get the imports used to resolve class names.
     */
    public Imports getImports() {
        if (env == null)  return null; // lame default
        return env.getImports();
    }

    /**
     * Create a new class.
     */
    public ClassDefinition makeClassDefinition(Environment origEnv, long where,
                                               IdentifierToken name,
                                               String doc, int modifiers,
                                               IdentifierToken superClass,
                                               IdentifierToken interfaces[],
                                               ClassDefinition outerClass) {
        if (env == null)  return null; // lame default
        return env.makeClassDefinition(origEnv, where, name,
                                       doc, modifiers,
                                       superClass, interfaces, outerClass);
    }

    /**
     * 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 (env == null)  return null; // lame default
        return env.makeMemberDefinition(origEnv, where, clazz, doc, modifiers,
                                       type, name, argNames, expIds, value);
    }

    /**
     * Returns true if the given method is applicable to the given arguments
     */

    public boolean isApplicable(MemberDefinition m, Type args[]) throws ClassNotFound {
        Type mType = m.getType();
        if (!mType.isType(TC_METHOD))
            return false;
        Type mArgs[] = mType.getArgumentTypes();
        if (args.length != mArgs.length)
            return false;
        for (int i = args.length ; --i >= 0 ;)
            if (!isMoreSpecific(args[i], mArgs[i]))
                return false;
        return true;
    }


    /**
     * Returns true if "best" is in every argument at least as good as "other"
     */
    public boolean isMoreSpecific(MemberDefinition best, MemberDefinition other)
           throws ClassNotFound {
        Type bestType = best.getClassDeclaration().getType();
        Type otherType = other.getClassDeclaration().getType();
        boolean result = isMoreSpecific(bestType, otherType)
                      && isApplicable(other, best.getType().getArgumentTypes());
        // System.out.println("isMoreSpecific: " + best + "/" + other
        //                      + " => " + result);
        return result;
    }

    /**
     * Returns true if "from" is a more specific type than "to"
     */

    public boolean isMoreSpecific(Type from, Type to) throws ClassNotFound {
        return implicitCast(from, to);
    }

    /**
     * Return true if an implicit cast from this type to
     * the given type is allowed.
     */
    public boolean implicitCast(Type from, Type to) throws ClassNotFound {
        if (from == to)
            return true;

        int toTypeCode = to.getTypeCode();

        switch(from.getTypeCode()) {
        case TC_BYTE:
            if (toTypeCode == TC_SHORT)
                return true;
        case TC_SHORT:
        case TC_CHAR:
            if (toTypeCode == TC_INT) return true;
        case TC_INT:
            if (toTypeCode == TC_LONG) return true;
        case TC_LONG:
            if (toTypeCode == TC_FLOAT) return true;
        case TC_FLOAT:
            if (toTypeCode == TC_DOUBLE) return true;
        case TC_DOUBLE:
        default:
            return false;

        case TC_NULL:
            return to.inMask(TM_REFERENCE);

        case TC_ARRAY:
            if (!to.isType(TC_ARRAY)) {
                return (to == Type.tObject || to == Type.tCloneable
                           || to == Type.tSerializable);
            } else {
                // both are arrays.  recurse down both until one isn't an array
                do {
                    from = from.getElementType();
                    to = to.getElementType();
                } while (from.isType(TC_ARRAY) && to.isType(TC_ARRAY));
                if (  from.inMask(TM_ARRAY|TM_CLASS)
                      && to.inMask(TM_ARRAY|TM_CLASS)) {
                    return isMoreSpecific(from, to);
                } else {
                    return (from.getTypeCode() == to.getTypeCode());
                }
            }

        case TC_CLASS:
            if (toTypeCode == TC_CLASS) {
                ClassDefinition fromDef = getClassDefinition(from);
                ClassDefinition toDef = getClassDefinition(to);
                return toDef.implementedBy(this,
                                           fromDef.getClassDeclaration());
            } else {
                return false;
            }
        }
    }


    /**
     * Return true if an explicit cast from this type to
     * the given type is allowed.
     */
    public boolean explicitCast(Type from, Type to) throws ClassNotFound {
        if (implicitCast(from, to)) {
            return true;
        }
        if (from.inMask(TM_NUMBER)) {
            return to.inMask(TM_NUMBER);
        }
        if (from.isType(TC_CLASS) && to.isType(TC_CLASS)) {
            ClassDefinition fromClass = getClassDefinition(from);
            ClassDefinition toClass = getClassDefinition(to);
            if (toClass.isFinal()) {
                return fromClass.implementedBy(this,
                                               toClass.getClassDeclaration());
            }
            if (fromClass.isFinal()) {
                return toClass.implementedBy(this,
                                             fromClass.getClassDeclaration());
            }

            // The code here used to omit this case.  If both types
            // involved in a cast are interfaces, then JLS 5.5 requires
            // that we do a simple test -- make sure none of the methods
            // in toClass and fromClass have the same signature but
            // different return types.  (bug number 4028359)
            if (toClass.isInterface() && fromClass.isInterface()) {
                return toClass.couldImplement(fromClass);
            }

            return toClass.isInterface() ||
                   fromClass.isInterface() ||
                   fromClass.superClassOf(this, toClass.getClassDeclaration());
        }
        if (to.isType(TC_ARRAY)) {
            if (from.isType(TC_ARRAY))  {
                Type t1 = from.getElementType();
                Type t2 = to.getElementType();
                while ((t1.getTypeCode() == TC_ARRAY)
                       && (t2.getTypeCode() == TC_ARRAY)) {
                    t1 = t1.getElementType();
                    t2 = t2.getElementType();
                }
                if (t1.inMask(TM_ARRAY|TM_CLASS) &&
                    t2.inMask(TM_ARRAY|TM_CLASS)) {
                    return explicitCast(t1, t2);
                }
            } else if (from == Type.tObject || from == Type.tCloneable
                          || from == Type.tSerializable)
                return true;
        }
        return false;
    }

    /**
     * Flags.
     */
    public int getFlags() {
        return env.getFlags();
    }

    /**
     * Debugging flags.  There used to be a method debug()
     * that has been replaced because -g has changed meaning
     * (it now cooperates with -O and line number, variable
     * range and source file info can be toggled separately).
     */
    public final boolean debug_lines() {
        return (getFlags() & F_DEBUG_LINES) != 0;
    }
    public final boolean debug_vars() {
        return (getFlags() & F_DEBUG_VARS) != 0;
    }
    public final boolean debug_source() {
        return (getFlags() & F_DEBUG_SOURCE) != 0;
    }

    /**
     * Optimization flags.  There used to be a method optimize()
     * that has been replaced because -O has changed meaning in
     * javac to be replaced with -O and -O:interclass.
     */
    public final boolean opt() {
        return (getFlags() & F_OPT) != 0;
    }
    public final boolean opt_interclass() {
        return (getFlags() & F_OPT_INTERCLASS) != 0;
    }

    /**
     * Verbose
     */
    public final boolean verbose() {
        return (getFlags() & F_VERBOSE) != 0;
    }

    /**
     * Dump debugging stuff
     */
    public final boolean dump() {
        return (getFlags() & F_DUMP) != 0;
    }

    /**
     * Verbose
     */
    public final boolean warnings() {
        return (getFlags() & F_WARNINGS) != 0;
    }

    /**
     * Dependencies
     */
    public final boolean dependencies() {
        return (getFlags() & F_DEPENDENCIES) != 0;
    }

    /**
     * Print Dependencies to stdout
     */
    public final boolean print_dependencies() {
        return (getFlags() & F_PRINT_DEPENDENCIES) != 0;
    }

    /**
     * Deprecation warnings are enabled.
     */
    public final boolean deprecation() {
        return (getFlags() & F_DEPRECATION) != 0;
    }

    /**
     * Do not support virtual machines before version 1.2.
     * This option is not supported and is only here for testing purposes.
     */
    public final boolean version12() {
        return (getFlags() & F_VERSION12) != 0;
    }

    /**
     * Floating point is strict by default
     */
    public final boolean strictdefault() {
        return (getFlags() & F_STRICTDEFAULT) != 0;
    }

    /**
     * Release resources, if any.
     */
    public void shutdown() {
        if (env != null) {
            env.shutdown();
        }
    }

    /**
     * Issue an error.
     *  source   - the input source, usually a file name string
     *  offset   - the offset in the source of the error
     *  err      - the error number (as defined in this interface)
     *  arg1     - an optional argument to the error (null if not applicable)
     *  arg2     - a second optional argument to the error (null if not applicable)
     *  arg3     - a third optional argument to the error (null if not applicable)
     */
    public void error(Object source, long where, String err, Object arg1, Object arg2, Object arg3) {
        env.error(source, where, err, arg1, arg2, arg3);
    }
    public final void error(long where, String err, Object arg1, Object arg2, Object arg3) {
        error(source, where, err, arg1, arg2, arg3);
    }
    public final void error(long where, String err, Object arg1, Object arg2) {
        error(source, where, err, arg1, arg2, null);
    }
    public final void error(long where, String err, Object arg1) {
        error(source, where, err, arg1, null, null);
    }
    public final void error(long where, String err) {
        error(source, where, err, null, null, null);
    }

    /**
     * Output a string. This can either be an error message or something
     * for debugging. This should be used instead of println.
     */
    public void output(String msg) {
        env.output(msg);
    }

    private static boolean debugging = (System.getProperty("javac.debug") != null);

    public static void debugOutput(Object msg) {
        if (Environment.debugging)
            System.out.println(msg.toString());
    }

    /**
     * set character encoding name
     */
    public void setCharacterEncoding(String encoding) {
        this.encoding = encoding;
    }

    /**
     * Return character encoding name
     */
    public String getCharacterEncoding() {
        return encoding;
    }

    /**
     * Return major version to use in generated class files.
     */
    public short getMajorVersion() {
        if (env==null) return JAVA_DEFAULT_VERSION;  // needed for javah
        return env.getMajorVersion();
    }

    /**
     * Return minor version to use in generated class files.
     */
    public short getMinorVersion() {
        if (env==null) return JAVA_DEFAULT_MINOR_VERSION;  // needed for javah
        return env.getMinorVersion();
    }

// JCOV
    /**
     *  get coverage flag
     */
    public final boolean coverage() {
        return (getFlags() & F_COVERAGE) != 0;
    }

    /**
     *  get flag of generation the coverage data file
     */
    public final boolean covdata() {
        return (getFlags() & F_COVDATA) != 0;
    }

    /**
     * Return the coverage data file
     */
    public File getcovFile() {
        return env.getcovFile();
    }

// end JCOV

    /**
     * Debug tracing.
     * Currently, this code is used only for tracing the loading and
     * checking of classes, particularly the demand-driven aspects.
     * This code should probably be integrated with 'debugOutput' above,
     * but we need to give more thought to the issue of classifying debugging
     * messages and allowing those only those of interest to be enabled.
     *
     * Calls to these methods are generally conditioned on the final variable
     * 'Constants.tracing', which allows the calls to be completely omitted
     * in a production release to avoid space and time overhead.
     */

    private static boolean dependtrace =
                (System.getProperty("javac.trace.depend") != null);

    public void dtEnter(String s) {
        if (dependtrace) System.out.println(">>> " + s);
    }

    public void dtExit(String s) {
        if (dependtrace) System.out.println("<<< " + s);
    }

    public void dtEvent(String s) {
        if (dependtrace) System.out.println(s);
    }

    /**
     * Enable diagnostic dump of class modifier bits, including those
     * in InnerClasses attributes, as they are written to the classfile.
     * In the future, may also enable dumping field and method modifiers.
     */

    private static boolean dumpmodifiers =
                (System.getProperty("javac.dump.modifiers") != null);

    public boolean dumpModifiers() { return dumpmodifiers; }

}
