313 lines · 11.5 KB · Java
RawDownload
/* * Copyright (c) 1994, 2004, Oracle and/or its affiliates. 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.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.tools.javac; import sun.tools.java.*;import sun.tools.tree.*; import java.io.IOException;import java.io.InputStream;import java.util.Vector;import java.util.Enumeration; /** * Batch file parser, 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. */@Deprecatedpublicclass BatchParser extends Parser {    /**     * The current package     */    protected Identifier pkg;     /**     * The current imports     */    protected Imports imports;     /**     * The classes defined in this file     */    protected Vector classes;      /**     * The current class     */    protected SourceClass sourceClass;     /**     * The toplevel environment     */    protected Environment toplevelEnv;     /**     * Create a batch file parser     */    public BatchParser(Environment env, InputStream in) throws IOException {        super(env, in);         imports = new Imports(env);        classes = new Vector();        toplevelEnv = imports.newEnvironment(env);    }     /**     * Package declaration     */    public void packageDeclaration(long where, IdentifierToken t) {        Identifier nm = t.getName();        //System.out.println("package " + nm);        if (pkg == null) {            // This code has been changed to pass an IdentifierToken,            // rather than an Identifier, to setCurrentPackage().  Imports            // now needs the location of the token.            pkg = t.getName();            imports.setCurrentPackage(t);        } else {            env.error(where, "package.repeated");        }    }     /**     * Import class     */    public void importClass(long pos, IdentifierToken t) {        //System.out.println("import class " + t);        imports.addClass(t);    }     /**     * Import package     */    public void importPackage(long pos, IdentifierToken t) {        //System.out.println("import package " + t);        imports.addPackage(t);    }     /**     * Define class     */    public ClassDefinition beginClass(long where, String doc, int mod,                                      IdentifierToken t,                                      IdentifierToken sup,                                      IdentifierToken interfaces[]) {         // If this class is nested, the modifier bits set here will        // be copied into the 'SourceMember' object for the inner class        // created during the call to 'makeClassDefinition' below.        // When writing the class file, we will look there for the        // 'untransformed' modifiers.  The modifiers in the ClassDefinition        // object will end up as the 'transformed' modifiers.  Note that        // there are some bits set here that are not legal class modifiers        // according to the JVMS, e.g., M_PRIVATE and M_STATIC.  These are        // masked off while writing the class file, but are preserved in        // the InnerClasses attributes.         if (tracing) toplevelEnv.dtEnter("beginClass: " + sourceClass);         SourceClass outerClass = sourceClass;         if (outerClass == null && pkg != null) {            t = new IdentifierToken(t.getWhere(),                                    Identifier.lookup(pkg, t.getName()));        }         // The defaults for anonymous and local classes should be documented!         if ((mod & M_ANONYMOUS) != 0) {            mod |= (M_FINAL | M_PRIVATE);        }        if ((mod & M_LOCAL) != 0) {            mod |= M_PRIVATE;        }         // Certain modifiers are implied as follows:        //        // 1.  Any interface (nested or not) is implicitly deemed to be abstract,        //     whether it is explicitly marked so or not.  (Java 1.0.)        // 2.  A interface which is a member of a type is implicitly deemed to        //     be static, whether it is explicitly marked so or not.  (InnerClasses)        // 3a. A type which is a member of an interface is implicitly deemed        //     to be public, whether it is explicitly marked so or not. (InnerClasses)        // 3b. A type which is a member of an interface is implicitly deemed        //     to be static, whether it is explicitly marked so or not. (InnerClasses)         if ((mod & M_INTERFACE) != 0) {            // Rule 1.            mod |= M_ABSTRACT;            if (outerClass != null) {                // Rule 2.                mod |= M_STATIC;            }        }         if (outerClass != null && outerClass.isInterface()) {            // Rule 3a.            // For interface members, neither 'private' nor 'protected'            // are legal modifiers.  We avoid setting M_PUBLIC in some            // cases in order to avoid interfering with error detection            // and reporting.  This is patched up, after reporting an            // error, by 'SourceClass.addMember'.            if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)                mod |= M_PUBLIC;            // Rule 3b.            mod |= M_STATIC;        }         // For nested classes, we must transform 'protected' to 'public'        // and 'private' to package scope.  This must be done later,        // because any modifiers set here will be copied into the        // 'MemberDefinition' for the nested class, which must represent        // the original untransformed modifiers.  Also, compile-time        // checks should be performed against the actual, untransformed        // modifiers.  This is in contrast to transformations that implement        // implicit modifiers, such as M_STATIC and M_FINAL for fields        // of interfaces.         sourceClass = (SourceClass)            toplevelEnv.makeClassDefinition(toplevelEnv, where, t,                                            doc, mod, sup,                                            interfaces, outerClass);         sourceClass.getClassDeclaration().setDefinition(sourceClass, CS_PARSED);        env = new Environment(toplevelEnv, sourceClass);         if (tracing) toplevelEnv.dtEvent("beginClass: SETTING UP DEPENDENCIES");         // The code which adds artificial dependencies between        // classes in the same source file has been moved to        // BatchEnvironment#parseFile().         if (tracing) toplevelEnv.dtEvent("beginClass: ADDING TO CLASS LIST");         classes.addElement(sourceClass);         if (tracing) toplevelEnv.dtExit("beginClass: " + sourceClass);         return sourceClass;    }     /**     * Report the current class under construction.     */    public ClassDefinition getCurrentClass() {        return sourceClass;    }     /**     * End class     */    public void endClass(long where, ClassDefinition c) {         if (tracing) toplevelEnv.dtEnter("endClass: " + sourceClass);         // c == sourceClass; don't bother to check        sourceClass.setEndPosition(where);        SourceClass outerClass = (SourceClass) sourceClass.getOuterClass();        sourceClass = outerClass;        env = toplevelEnv;        if (sourceClass != null)            env = new Environment(env, sourceClass);         if (tracing) toplevelEnv.dtExit("endClass: " + sourceClass);    }     /**     * Define a method     */    public void defineField(long where, ClassDefinition c,                            String doc, int mod, Type t,                            IdentifierToken name, IdentifierToken args[],                            IdentifierToken exp[], Node val) {        // c == sourceClass; don't bother to check        Identifier nm = name.getName();        // Members that are nested classes are not created with 'defineField',        // so these transformations do not apply to them.  See 'beginClass' above.        if (sourceClass.isInterface()) {            // Members of interfaces are implicitly public.            if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)                // For interface members, neither 'private' nor 'protected'                // are legal modifiers.  Avoid setting M_PUBLIC in some cases                // to avoid interfering with later error detection.  This will                // be fixed up after the error is reported.                mod |= M_PUBLIC;            // Methods of interfaces are implicitly abstract.            // Fields of interfaces are implicitly static and final.            if (t.isType(TC_METHOD)) {                mod |= M_ABSTRACT;            } else {                mod |= M_STATIC | M_FINAL;            }        }        if (nm.equals(idInit)) {            // The parser reports "idInit" when in reality it has found            // that there is no method name at all present.            // So, decide if it's really a constructor, or a syntax error.            Type rt = t.getReturnType();            Identifier retname = !rt.isType(TC_CLASS) ? idStar /*no match*/                                                      : rt.getClassName();            Identifier clsname = sourceClass.getLocalName();            if (clsname.equals(retname)) {                t = Type.tMethod(Type.tVoid, t.getArgumentTypes());            } else if (clsname.equals(retname.getFlatName().getName())) {                // It appears to be a constructor with spurious qualification.                t = Type.tMethod(Type.tVoid, t.getArgumentTypes());                env.error(where, "invalid.method.decl.qual");            } else if (retname.isQualified() || retname.equals(idStar)) {                // It appears to be a type name with no method name.                env.error(where, "invalid.method.decl.name");                return;            } else {                // We assume the type name is missing, even though the                // simple name that's present might have been intended                // to be a type:  "String (){}" vs. "toString(){}".                env.error(where, "invalid.method.decl");                return;            }        }         if (args == null && t.isType(TC_METHOD)) {            args = new IdentifierToken[0];        }         if (exp == null && t.isType(TC_METHOD)) {            exp = new IdentifierToken[0];        }         MemberDefinition f = env.makeMemberDefinition(env, where, sourceClass,                                                    doc, mod, t, nm,                                                    args, exp, val);        if (env.dump()) {            f.print(System.out);        }    }}