summaryrefslogblamecommitdiff
path: root/sources/scalac/symtab/classfile/CLRPackageParser.java
blob: f6578a4aff6342c4ad1bac97250d90a5f249b873 (plain) (tree)



















                                                                          
                                  


                           
                                   



                     
                                                    


                                                                                

















                             





























                                                                                    












                                            
                                         



                                                  


                                   
                                       















                                                                              



                           

                                                       





                                                                                
                                                    










                                                 


                                    














                                                                                
                                                
                                                     

                              

                                                                         

                                             
                         
                                                      





                                      
                                                             



                                                                         


                                                          





                                          








                                                      






                                                                      
                                      

















                                                                                
                                           
                         
                     




                                                                           








                                                                     


                                                           

                                                          

                       










                                                                               
                                                                                          
                                     













                                                                     
                                               




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

// $Id$

package scalac.symtab.classfile;

import java.util.List;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.HashMap;

import java.io.File;

import ch.epfl.lamp.compiler.msil.*;
import scalac.symtab.Symbol;
import scalac.symtab.SymbolLoader;
import scalac.symtab.Scope;
import scalac.util.Debug;
import scalac.util.Name;
import scalac.util.NameTransformer;
import scalac.Global;

/**
 */
public class CLRPackageParser extends SymbolLoader {

    //##########################################################################

    public Type BYTE;
    public Type UBYTE;
    public Type CHAR;
    public Type SHORT;
    public Type USHORT;
    public Type INT;
    public Type UINT;
    public Type LONG;
    public Type ULONG;
    public Type FLOAT;
    public Type DOUBLE;
    public Type BOOLEAN;
    public Type VOID;
    public Type ENUM;

    public Type OBJECT;
    public Type STRING;
    public Type STRING_ARRAY;

    protected CLRClassParser completer;

    private CLRPackageParser(Global global) {
	super(global);
    }

    public static CLRPackageParser instance;
    public static CLRPackageParser create(Global global) {
	if (instance != null)
	    return instance;
	instance = new CLRPackageParser(global);
	instance.completer = new CLRClassParser(global, instance);
	instance.init();
	return instance;
    }

    Type[] types;

    public Type[] getTypes() { return types; }

    private boolean initialized = false;
    public void init() {
	if (initialized) return;
	String[] asnames = scalac.util.ClassPath.parse(global.args.assemrefs.value);
	for (int i = 0; i < asnames.length; i++)
	    assemrefs.add(asnames[i]);
	Assembly mscorlib = findAssembly("mscorlib.dll");
	Type.initMSCORLIB(mscorlib);

	BYTE    = getType("System.SByte");
	UBYTE   = getType("System.Byte");
	CHAR    = getType("System.Char");
	SHORT   = getType("System.Int16");
	USHORT  = getType("System.UInt16");
	INT     = getType("System.Int32");
	UINT    = getType("System.UInt32");
	LONG    = getType("System.Int64");
	ULONG   = getType("System.UInt64");
	FLOAT   = getType("System.Single");
	DOUBLE  = getType("System.Double");
	BOOLEAN = getType("System.Boolean");
	VOID    = getType("System.Void");
	ENUM    = getType("System.Enum");

	OBJECT = getType("System.Object");
	STRING = getType("System.String");
	STRING_ARRAY = getType("System.String[]");

 	findAssembly("vjslib.dll");
   	findAssembly("scala.dll");
   	//findAssembly("scalalib.dll");
	findAllAssemblies();

	Type[] types = Type.EmptyTypes;
	Iterator as = assemblies.iterator();
	while (as.hasNext()) {
	    Type[] atypes = ((Assembly)as.next()).GetTypes();
	    int j = 0;
	    for (int i = 0; i < atypes.length; i++)
		if (/*atypes[i].IsPublic && */atypes[i].DeclaringType == null)
		    atypes[j++] = atypes[i];
	    Type[] btypes = new Type[types.length + j];
	    System.arraycopy(types, 0, btypes, 0, types.length);
	    System.arraycopy(atypes, 0, btypes, types.length, j);
	    types = btypes;
	}
	this.types = types;
	initialized = true;
    }


    private java.util.Map syms2members = new HashMap();
    private java.util.Map members2syms = new HashMap();

    //##########################################################################

    public void map(Symbol sym, MemberInfo m) {
	syms2members.put(sym, m);
	members2syms.put(m, sym);
	//System.out.println("" + sym + " => " + m);
    }

    public MemberInfo getMember(Symbol sym) {
	return (MemberInfo)syms2members.get(sym);
    }

    public Symbol getSymbol(MemberInfo m) {
	return (Symbol)members2syms.get(m);
    }

    public Type getType(String name) {
	Type t = Type.GetType(name);
	//assert t != null : name;
	return t;
    }

    public Type mkArrayType(Type elemType) {
	return getType(elemType.FullName + "[]");
    }

    //##########################################################################
    // assembly loading methods

    protected final java.util.List assemblies = new LinkedList();

    protected final java.util.List assemrefs = new LinkedList();

    /** Load the assembly with the given name
     */
    private Assembly findAssembly(String name) {
	// see if the assembly is referenced directly
	File file = null;
	Assembly assem = null;
	for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
	    String assemname = (String)assems.next();
	    file = new File(assemname);
	    if (!file.getName().equals(name))
		continue;
	    assem = Assembly.LoadFrom(file.getPath());
	    if (assem != null) {
		assems.remove();
		assemblies.add(assem);
		return assem;
	    }
	}
	// look in directories specified with the '-r' option
	for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
	    File d = new File((String)assems.next());
	    if (!d.isDirectory())
		continue;
	    file = new File(d, name);
	    if (file.exists()) {
		assem = Assembly.LoadFrom(file.getPath());
		if (assem != null) {
		    assemblies.add(assem);
		    return assem;
		}
	    }
	}
	// try in the current directory
	file = new File(".", name);
	if (file.exists()) {
	    assem = Assembly.LoadFrom(file.getPath());
	    if (assem != null) {
		assemblies.add(assem);
		return assem;
	    }
	}
	global.fail("Cannot find assembly " + name
		    + "; use the -r option to specify its location");
	return null;
    }

    /** Load the rest of the assemblies specified with the '-r' option
     */
    private void findAllAssemblies() {
	//System.out.println("assembly references left: " + assemrefs);
	for (Iterator assems = assemrefs.iterator(); assems.hasNext();) {
	    File f = new File((String)assems.next());
	    if (f.isFile()) {
		Assembly assem = Assembly.LoadFrom(f.getPath());
		if (assem != null) {
		    assemblies.add(assem);
		    //System.out.println("Loaded assembly " + assem);
		}
	    }
	    assems.remove();
	}
	assert assemrefs.isEmpty();
    }

    //##########################################################################
    // main functionality

    protected String doComplete(Symbol p) {
	// for future use
        return "!!!";
    }

    /**
     */
    public void importCLRTypes(Symbol p, Scope members, PackageParser pp) {
	if (p.isRoot()) {
	    for (int i = 0; i < types.length; i++) {
		int j = types[i].FullName.indexOf('.');
		if (j < 0) continue;
		String namespace = types[i].FullName.substring(0, j);
		importCLRNamespace(namespace, p, members, pp);
	    }
	    return;
	}
        String n1 = "";
        for (Symbol q = p; !q.isRoot(); q = q.owner()) {
            n1 = NameTransformer.decode(q.name) + "." + n1;
            if (q.module() == global.definitions.JAVA
                || q.module() == global.definitions.SCALA)
                return;
        }
	for (int i = 0; i < types.length; i++) {
	    String fullname = types[i].FullName;
	    if (!fullname.startsWith(n1))
		continue;
	    //System.out.println("importing type: " + fullname);
	    int j = n1.length();
	    int k = fullname.indexOf('.', j);
	    String name = fullname.substring(j, k < 0 ? fullname.length() : k);
	    Name n = Name.fromString(name);
	    if (k < 0) {
		// it's a class
                Symbol clazz = p.newLoadedClass(JAVA, n.toTypeName(), completer, members);
		map(clazz, types[i]);
	    } else {
		importCLRNamespace(name, p, members, pp);
	    }
	}
    }

    /** Imports a CLR namespace as a scala package.
     */
    protected void importCLRNamespace(String namespace, Symbol p,
				   Scope members, PackageParser pp)
    {
	Name n = Name.fromString(namespace);
	if (members.lookup(n) == Symbol.NONE) {
	    //System.out.println("importing namespace " + namespace);
	    p.newLoadedPackage(n, pp, members);
	}
    }

    //##########################################################################
}