summaryrefslogblamecommitdiff
path: root/sources/scalac/symtab/classfile/PackageParser.java
blob: 9fdbe797ed8489fd449d86421976dc06cd8d6c82 (plain) (tree)























                                                                          
                                                      



                                                       


                                                                         











                                                                               
                                                                     































                                                                                    

                                                                                   

                                                        


                                                                  











                                                                                        




                                                                                        
                                                           
                     
                                                                     
                                                                  

                                                                                    

                                                  
                                          


                                                                                   

                                                                         

                                                                






                                                                                    
                                          

                                                                                   
                                                                                
                                                                             

                                                                   


                                                          
                                                     
                     




                                 
 
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
**                                                                      **
** $Id$
\*                                                                      */

package scalac.symtab.classfile;

import scalac.*;
import scalac.symtab.*;
import scalac.util.*;
import java.io.*;

public class PackageParser extends Type.LazyType {

    /** the global compilation environment
     */
    protected Global global;

    /** the class parser
     */
    public ClassParser classCompletion;
    public SymblParser symblCompletion; // provisional

    public PackageParser(Global global) {
        this.global = global;
        this.classCompletion = new ClassParser(global);
	this.symblCompletion = new SymblParser(global); // provisional
	if (global.reporter.verbose)
	    System.out.println("classpath = " + global.classPath);//debug
    }

    /** complete package type symbol p by loading all package members
     */
    public void complete(Symbol p) {
        long msec = System.currentTimeMillis();
        Scope members = new Scope();
        String dirname = null;
        Name name = p.fullName();
        if (name.length() == 0) {
            // includeMembers(AbstractFile.open(null, "."), p, members, false);
        } else {
            dirname = SourceRepresentation.externalizeFileName(name);
	    assert !dirname.startsWith("com") : p;//debug
            if (!dirname.endsWith("/"))
                dirname += "/";
        }
        String[] base = global.classPath.components();
        for (int i = 0; i < base.length; i++) {
            includeMembers(
		AbstractFile.open(base[i], dirname), p, members, dirname != null);
	}
        p.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, p));
        if (dirname == null)
            dirname = "anonymous package";
        global.operation("scanned " + dirname + " in " +
                    (System.currentTimeMillis() - msec) + "ms");
    }

    /** read directory of a classpath directory and include members
     *  in package/module scope
     */
    protected void includeMembers(AbstractFile dir, Symbol p, Scope locals,
				  boolean inclClasses) {
        if (dir == null)
            return;
        String[] filenames = null;
        try {
            if ((filenames = dir.list()) == null)
                return;
            for (int j = 0; j < filenames.length; j++) {
                String fname = filenames[j];
                if (inclClasses && fname.endsWith(".class")) {
                    Name n = Name.fromString(fname.substring(0, fname.length() - 6))
			.toTypeName();
                    if (locals.lookup(n) == Symbol.NONE) {
		        ClassSymbol clazz = new ClassSymbol(n, p, classCompletion);
			// todo: needed?
		        clazz.allConstructors().setInfo(
			    classCompletion.staticsParser(clazz));
		        // enter class
		        locals.enter(clazz);
		        // enter module, except for scala.Object class
		        // todo: why not there also?.
		        if (!(n == Names.Object.toTypeName() &&
			      p.fullName().toTermName() == Names.scala)) {
			    Scope.Entry e = locals.lookupEntry(clazz.module().name);
			    if (e != Scope.Entry.NONE) {
			        // we already have a package of the same name; delete it
			        locals.unlink(e);
			    }
			    locals.enter(clazz.module());
		        }
                    }
                } else if (fname.endsWith("/") && !fname.equals("META-INF/")) {
                    Name n = Name.fromString(fname.substring(0, fname.length() - 1));
                    if (locals.lookup(n) == Symbol.NONE) {
                        TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this);
                        locals.enter(module);
			locals.enter(module.moduleClass());
                    }
		} else if (inclClasses && fname.endsWith(".symbl")) {
		    //todo: compare dates between symbl and scala.
                    Name n = Name.fromString(fname.substring(0, fname.length() - 6))
			.toTypeName();
		    Symbol sym = locals.lookup(n);
		    if (sym == Symbol.NONE ||
			sym.isPackage() ||
			sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser &&
			!(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) {
			ClassSymbol clazz = new ClassSymbol(n, p, symblCompletion);
			//todo: needed
			clazz.allConstructors().setInfo(symblCompletion);
			clazz.module().setInfo(symblCompletion);
			locals.enter(clazz);
			locals.enter(clazz.module());
		    }
                } else if (inclClasses && fname.endsWith(".scala")) {
                    Name n = Name.fromString(fname.substring(0, fname.length() - 6))
			.toTypeName();
		    Symbol sym = locals.lookup(n);
		    if (sym == Symbol.NONE ||
			sym.isPackage() ||
			sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser &&
			!(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) {
                        SourceCompleter completer = new SourceCompleter(global);
                        ClassSymbol clazz = new ClassSymbol(n, p, completer);
			//todo: needed?
                        clazz.allConstructors().setInfo(completer);
			clazz.module().setInfo(completer);
                        // enter class
                        locals.enter(clazz);
			locals.enter(clazz.module());
                    }
                }
            }
        } catch (IOException e) {
        }
    }
}