summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
new file mode 100644
index 0000000000..f90f6d6624
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
@@ -0,0 +1,254 @@
+/* NSC -- new scala compiler
+ * Copyright 2004-2006 LAMP/EPFL
+ */
+
+// $Id: CLRTypes.scala 9524 2006-12-14 17:54:07Z mihaylov $
+
+package scala.tools.nsc.symtab.clr;
+
+import scala.tools.nsc.util.Position;
+
+import scala.collection.mutable.{ListBuffer, Map, HashMap, Set, HashSet};
+import java.util.{Arrays, Comparator, StringTokenizer};
+
+import java.io.File;
+
+import ch.epfl.lamp.compiler.msil._;
+
+/**
+ * Collects all types from all reference assemblies.
+ */
+abstract class CLRTypes {
+
+ val global: Global;
+ import global.Symbol;
+ import global.definitions;
+
+ //##########################################################################
+
+ var BYTE: Type = _;
+ var UBYTE: Type = _;
+ var SHORT: Type = _;
+ var USHORT: Type = _;
+ var CHAR: Type = _;
+ var INT: Type = _;
+ var UINT: Type = _;
+ var LONG: Type = _;
+ var ULONG: Type = _;
+ var FLOAT: Type = _;
+ var DOUBLE: Type = _;
+ var BOOLEAN: Type = _;
+ var VOID: Type = _;
+ var ENUM: Type = _;
+ var DELEGATE: Type = _;
+
+ var OBJECT: Type = _;
+ var STRING: Type = _;
+ var STRING_ARRAY: Type = _;
+
+ var VALUE_TYPE: Type = _;
+
+ var SCALA_SYMTAB_ATTR: Type = _;
+ var SYMTAB_CONSTR: ConstructorInfo = _;
+ var SYMTAB_DEFAULT_CONSTR: ConstructorInfo = _;
+
+ var DELEGATE_COMBINE: MethodInfo = _;
+ var DELEGATE_REMOVE: MethodInfo = _;
+
+ val types: Map[Symbol,Type] = new HashMap;
+ val constructors: Map[Symbol,ConstructorInfo] = new HashMap;
+ val methods: Map[Symbol,MethodInfo] = new HashMap;
+ val fields: Map[Symbol, FieldInfo] = new HashMap;
+ val sym2type: Map[Type,Symbol] = new HashMap;
+
+ private var alltypes: Array[Type] = _;
+
+ def init(): Unit = { // initialize
+
+ val assems = new StringTokenizer(global.settings.assemrefs.value, File.pathSeparator);
+ while (assems.hasMoreTokens()) {
+ assemrefs += new File(assems.nextToken());
+ }
+
+ val mscorlib = findAssembly("mscorlib.dll");
+ Type.initMSCORLIB(mscorlib);
+ findAssembly("scalaruntime.dll");
+ findAllAssemblies();
+
+ BYTE = getTypeSafe("System.SByte");
+ UBYTE = getTypeSafe("System.Byte");
+ CHAR = getTypeSafe("System.Char");
+ SHORT = getTypeSafe("System.Int16");
+ USHORT = getTypeSafe("System.UInt16");
+ INT = getTypeSafe("System.Int32");
+ UINT = getTypeSafe("System.UInt32");
+ LONG = getTypeSafe("System.Int64");
+ ULONG = getTypeSafe("System.UInt64");
+ FLOAT = getTypeSafe("System.Single");
+ DOUBLE = getTypeSafe("System.Double");
+ BOOLEAN = getTypeSafe("System.Boolean");
+ VOID = getTypeSafe("System.Void");
+ ENUM = getTypeSafe("System.Enum");
+ DELEGATE = getTypeSafe("System.MulticastDelegate");
+
+ OBJECT = getTypeSafe("System.Object");
+ STRING = getTypeSafe("System.String");
+ STRING_ARRAY = getTypeSafe("System.String[]");
+ VALUE_TYPE = getTypeSafe("System.ValueType");
+
+ SCALA_SYMTAB_ATTR = getTypeSafe("scala.runtime.SymtabAttribute");
+ val bytearray: Array[Type] = Array( Type.GetType("System.Byte[]") );
+ SYMTAB_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(bytearray);
+ SYMTAB_DEFAULT_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(Type.EmptyTypes);
+
+ //assert(SCALA_SYMTAB_ATTR != null);
+
+ val delegate: Type = getTypeSafe("System.Delegate");
+ val dargs: Array[Type] = Array(delegate, delegate);
+ DELEGATE_COMBINE = delegate.GetMethod("Combine", dargs);
+ DELEGATE_REMOVE = delegate.GetMethod("Remove", dargs);
+ //assert(DELEGATE_COMBINE != null);
+ //assert(DELEGATE_REMOVE != null);
+
+
+ var alltypes: Array[Type] = Type.EmptyTypes;
+ for (val assem <- assemblies) {
+ val atypes = assem.GetTypes().filter((typ: Type) => typ.DeclaringType == null);
+ alltypes = Array.concat(alltypes, atypes);
+ }
+
+ val typeNameComparator: Comparator =
+ new Comparator() {
+ def compare(o1: Any, o2: Any): Int = {
+ val t1 = o1.asInstanceOf[Type];
+ val t2 = o2.asInstanceOf[Type];
+ t1.FullName.compareTo(t2.FullName);
+ }
+ };
+
+ Arrays.sort(alltypes.asInstanceOf[Array[Object]], typeNameComparator);
+ this.alltypes = alltypes;
+ }
+
+ //##########################################################################
+ // type mapping and lookup
+
+// private class MyHashMap[A, B <: AnyRef] extends HashMap[A, B] {
+// override def default(key: A): B = null;
+// }
+
+ def getType(name: String): Type = Type.GetType(name);
+
+ def getTypeSafe(name: String): Type = {
+ val t = Type.GetType(name);
+ assert(t != null, name);
+ t;
+ }
+
+ def mkArrayType(elemType: Type): Type = getType(elemType.FullName + "[]");
+
+ def isDelegateType(t: Type): Boolean = { t.BaseType() == DELEGATE }
+
+ //##########################################################################
+ // assembly loading methods
+
+ // a list of all loaded assemblies
+ private var assemblies: ListBuffer[Assembly] = new ListBuffer();
+
+ // a set of all directories and assembly files
+ private var assemrefs: Set[File] = new HashSet();
+
+ /** Load the assembly with the given name
+ */
+ private def findAssembly(name: String): Assembly = {
+ // see if the assembly is referenced directly
+ for (val file <- assemrefs.elements; file.getName() == name) {
+ val assem = Assembly.LoadFrom(file.getPath());
+ if (assem != null) {
+ assemrefs -= file;
+ assemblies += assem;
+ return assem;
+ }
+ }
+ // look in directories specified with the '-r' option
+ for (val dir <- assemrefs.elements; dir.isDirectory()) {
+ val file = new File(dir, name);
+ if (file.exists()) {
+ val assem = Assembly.LoadFrom(file.getPath());
+ if (assem != null) {
+ assemblies += assem;
+ return assem;
+ }
+ }
+ }
+ // try in the current directory
+ val file = new File(".", name);
+ if (file.exists()) {
+ val assem = Assembly.LoadFrom(file.getPath());
+ if (assem != null) {
+ assemblies += assem;
+ return assem;
+ }
+ }
+ global.reporter.error(new Position(null, Position.NOPOS),
+ "cannot find assembly " + name + "; use the -r option to specify its location");
+ throw new Error();
+ }
+
+ /** Load the rest of the assemblies specified with the '-r' option
+ */
+ private def findAllAssemblies(): Unit = {
+ for (val file <- assemrefs.elements) {
+ if (file.isFile()) {
+ //System.out.println("Loading assembly " + file)
+ val assem = Assembly.LoadFrom(file.getPath());
+ if (assem != null) {
+ assemblies += assem;
+ }
+ }
+ assemrefs -= file;
+ }
+ assert(assemrefs.isEmpty, assemrefs.toString());
+ }
+
+ //##########################################################################
+ // collect the members contained in a given namespace
+
+ /** Find the position of the first type whose name starts with
+ * the given prefix; return the length of the types array if no match
+ * is found so the result can be used to terminate loop conditions
+ */
+ private def findFirst(prefix: String): Int = {
+ var m = 0;
+ var n = alltypes.length - 1;
+ while (m < n) {
+ val l = (m + n) / 2;
+ val res = alltypes(l).FullName.compareTo(prefix);
+ if (res < 0) m = l + 1;
+ else n = l;
+ }
+ if (alltypes(m).FullName.startsWith(prefix)) m else alltypes.length;
+ }
+
+ /** Collects the members contained in the given Scala package (namespace)
+ */
+ def collectMembers(pakage: Symbol, typesMap: Map[String,Type], namespacesSet: Set[String]) = {
+ val namespace = if (pakage.isRoot) "" else pakage.fullNameString + ".";
+ val nl = namespace.length();
+ var i = findFirst(namespace);
+ while (i < alltypes.length && alltypes(i).FullName.startsWith(namespace)) {
+ val typ = alltypes(i);
+ if (typ.FullName != "java.lang.Object" && typ.FullName != "java.lang.String") {
+ val k = typ.FullName.indexOf(".", nl);
+ if (k < 0) {
+ typesMap.update(typ.Name, typ);
+ } else {
+ namespacesSet += (typ.Namespace.substring(nl, k));
+ }
+ }
+ i = i + 1;
+ }
+ }
+
+ //##########################################################################
+} // CLRTypes