Milán Major

netscape-revival

1 branch
Code

sun-java/classsrc/sun/tools/javac/BatchParser.java

/*
 * @(#)BatchParser.java	1.26 95/11/13 Arthur van Hoff
 *
 * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

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.
 */

public final
class BatchParser extends Parser {
    /**
     * The current package
     */
    Identifier pkg;

    /**
     * The current imports
     */
    Imports imports;

    /**
     * The classes defined in this file
     */
    Vector classes;
     

    /**
     * The current class
     */
    SourceClass sourceClass;

    /**
     * The toplevel environment
     */
    Environment toplevelEnv;
    
    /**
     * Create a batch file parser
     */
    public BatchParser(Environment env, InputStream in) throws IOException {
	super(env, in);

	imports = new Imports();
	classes = new Vector();
	toplevelEnv = env;
    }

    /**
     * Resolve a name into a full class name
     */
    protected Identifier resolveClass(Identifier nm) {
	try {
	    return imports.resolve(env, nm);
	} catch (AmbiguousClass e) {
	    env.error(pos, "ambig.class", e.name1, e.name2);
	} catch (ClassNotFound e) {
	}
	return (pkg != null) ? Identifier.lookup(pkg, nm) : nm;
    }

    /**
     * Package declaration
     */
    protected void packageDeclaration(int where, Identifier nm) {
	//System.out.println("package " + nm);

	if (pkg == null) {
	    imports.addPackage(pkg = nm);
	} else {
	    env.error(where, "package.repeated");
	}
    }

    /**
     * Import class
     */
    protected void importClass(int where, Identifier nm) {
	//System.out.println("import class " + nm);
	try {
	    if (!env.classExists(nm)) {
		env.error(where, "class.not.found", nm, "import");
	    }
	    imports.addClass(nm);
	} catch (AmbiguousClass e) {
	    env.error(where, "ambig.class", e.name1, e.name2);
	}
    }

    /**
     * Import package
     */
    protected void importPackage(int where, Identifier nm) {
	try {
	    //println("import package " + nm);
	    Package p = env.getPackage(nm);
	    if (!p.exists()) {
		env.error(where, "package.not.found", nm, "import");
	    }
	    imports.addPackage(nm);
	} catch (IOException e) {
	    env.error(where, "io.exception", "import");
	}
    }

    /**
     * Define class
     */
    protected void beginClass(int where, String doc, int mod, Identifier nm,
			       Identifier sup, Identifier impl[]) {

	Identifier pkgNm = (pkg != null) ? Identifier.lookup(pkg, nm) : nm;

	// Does the name already exist in an imported package?
	try {
	    // We want this to throw a ClassNotFound exception
	    Identifier ID = imports.resolve(env, nm);
	    if (ID != pkgNm) 
		env.error(pos, "class.multidef.import", nm, ID);
	} catch (AmbiguousClass e) {
	    // At least one of e.name1 and e.name2 must be different
	    Identifier ID = (e.name1 != pkgNm) ? e.name1 : e.name2;
	    env.error(pos, "class.multidef.import", nm, ID);
	 }  catch (ClassNotFound e) {
	     // we want this to happen
	 }


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

	// Make sure this is the first definition
	if (c.isDefined()) {
	    env.error(where, "class.multidef", c.getName(), c.getClassDefinition().getSource());
	}

	// Find the super class
	ClassDeclaration superClass = null;
	if ((sup == null) || ((mod & M_INTERFACE) != 0)) {
	    superClass = env.getClassDeclaration(idJavaLangObject);
	} else if (!c.getName().equals(idJavaLangObject)) {
	    superClass = env.getClassDeclaration(sup);
	}

	// Find interfaces
	ClassDeclaration interfaces[] = new ClassDeclaration[impl.length];
	for (int i = 0 ; i < interfaces.length ; i++) {
	    interfaces[i] = env.getClassDeclaration(impl[i]);
	}

	sourceClass = new SourceClass(toplevelEnv, where, c, doc, mod, superClass, interfaces, imports);
	sourceClass.getClassDeclaration().setDefinition(sourceClass, CS_PARSED);
	env = new Environment(toplevelEnv, sourceClass);

	// Setup interdependencies between the classes in this file,
	// this is needed so that when one is recompiled, all are.
	for (Enumeration e = classes.elements() ; e.hasMoreElements() ;) {
	    ClassDefinition otherClass = (ClassDefinition)e.nextElement();
	    otherClass.addDependency(sourceClass.getClassDeclaration());
	    sourceClass.addDependency(otherClass.getClassDeclaration());
	}
	classes.addElement(sourceClass);
    }

    /**
     * End class
     */
    protected void endClass(int where, Identifier nm) {
	sourceClass = null;
	env = toplevelEnv;
    }

    /**
     * Define a method
     */
    protected void defineField(int where, String doc, int mod, Type t, Identifier nm,
			       Identifier args[], Identifier exp[], Node val) {
	if (sourceClass.isInterface()) {
	    mod |= M_PUBLIC;
	    if (t.isType(TC_METHOD)) {
		mod |= M_ABSTRACT;
	    } else {
		mod |= M_STATIC | M_FINAL;
	    }
	}
	if (nm.equals(idInit)) {
	    if (sourceClass.getType().equals(t.getReturnType())) {
		t = Type.tMethod(Type.tVoid, t.getArgumentTypes());
	    } else {
		env.error(where, "invalid.method.decl");
		return;
	    }
	}

	Vector v = null;
	if (args != null) {
	    v = new Vector(args.length);
	    for (int i = 0 ; i < args.length ; i++) {
		v.addElement(args[i]);
	    }
	} else if (t.isType(TC_METHOD)) {
	    v = new Vector();
	}

	ClassDeclaration exceptions[] = null;
	if (exp != null) {
	    exceptions = new ClassDeclaration[exp.length];
	    for (int i = 0 ; i < exp.length ; i++) {
		exceptions[i] = env.getClassDeclaration(exp[i]);
	    }
	} else if (t.isType(TC_METHOD)) {
	    exceptions = new ClassDeclaration[0];
	}

	SourceField f = new SourceField(where, sourceClass, doc, mod, t, nm, v, exceptions, val);
	sourceClass.addField(env, f);
	if (env.dump()) {
	    f.print(System.out);
	}
    }
}