/* ____ ____ ____ ____ ______ *\ ** / __// __ \/ __// __ \/ ____/ 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); } } //########################################################################## }