summaryrefslogtreecommitdiff
path: root/sources/scalac/backend
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2003-11-06 10:44:07 +0000
committermihaylov <mihaylov@epfl.ch>2003-11-06 10:44:07 +0000
commit300a10fbe48d9c9a2deadb92b703cd723959dc9f (patch)
tree4705ca9af243b23a58fd5471dc771104706478bf /sources/scalac/backend
parent302a8dfa191537784282a4302f2a6ae844f75a31 (diff)
downloadscala-300a10fbe48d9c9a2deadb92b703cd723959dc9f.tar.gz
scala-300a10fbe48d9c9a2deadb92b703cd723959dc9f.tar.bz2
scala-300a10fbe48d9c9a2deadb92b703cd723959dc9f.zip
- more extensive translation of java.lang.Strin...
- more extensive translation of java.lang.String methods code cleanups
Diffstat (limited to 'sources/scalac/backend')
-rw-r--r--sources/scalac/backend/msil/TypeCreator.java592
1 files changed, 354 insertions, 238 deletions
diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java
index 15c63e2915..6e4aaaaba9 100644
--- a/sources/scalac/backend/msil/TypeCreator.java
+++ b/sources/scalac/backend/msil/TypeCreator.java
@@ -25,7 +25,6 @@ import Tree.*;
import ch.epfl.lamp.compiler.msil.*;
import ch.epfl.lamp.compiler.msil.emit.*;
-//import ch.epfl.lamp.compiler.msil.util.VJSAssembly;
import java.util.Map;
import java.util.ArrayList;
@@ -57,126 +56,100 @@ final class TypeCreator {
static final String MODULE_S = "$MODULE";
- static final Type BYTE = Type.GetType("System.SByte");
- static final Type CHAR = Type.GetType("System.Char");
- static final Type SHORT = Type.GetType("System.Int16");
- static final Type INT = Type.GetType("System.Int32");
- static final Type LONG = Type.GetType("System.Int64");
- static final Type FLOAT = Type.GetType("System.Single");
- static final Type DOUBLE = Type.GetType("System.Double");
- static final Type BOOLEAN = Type.GetType("System.Boolean");
- static final Type VOID = Type.GetType("System.Void");
-
- static final Type SYSTEM_OBJECT = Type.GetType("System.Object");
- static final Type SYSTEM_STRING = Type.GetType("System.String");
- static final Type STRING_ARRAY = Type.GetType("System.String[]");
-
- static final Type MONITOR = Type.GetType("System.Threading.Monitor");
-
- static final MethodInfo CONCAT_OBJECT =
- SYSTEM_STRING.GetMethod("Concat", new Type[] {SYSTEM_OBJECT});
- static final MethodInfo CONCAT_STRING_STRING =
- SYSTEM_STRING.GetMethod("Concat", new Type[] {SYSTEM_STRING, SYSTEM_STRING});
- static final MethodInfo CONCAT_OBJECT_OBJECT =
- SYSTEM_STRING.GetMethod("Concat", new Type[] {SYSTEM_OBJECT, SYSTEM_OBJECT});
-
- static final MethodInfo OBJECT_EQUALS =
- SYSTEM_OBJECT.GetMethod("Equals", new Type[] {SYSTEM_OBJECT});
-
- static final MethodInfo MONITOR_PULSE =
- MONITOR.GetMethod("Pulse", new Type[] {SYSTEM_OBJECT});
-
- static final MethodInfo MONITOR_PULSE_ALL =
- MONITOR.GetMethod("PulseAll", new Type[] {SYSTEM_OBJECT});
-
- static final MethodInfo MONITOR_WAIT =
- MONITOR.GetMethod("Wait", new Type[] {SYSTEM_OBJECT});
-
- static final MethodInfo MONITOR_WAIT_TIMEOUT =
- MONITOR.GetMethod("Wait", new Type[] {SYSTEM_OBJECT, INT});
-
-
- final Type SCALA_BYTE;
- final Type SCALA_SHORT;
- final Type SCALA_INT;
- final Type SCALA_LONG;
- final Type SCALA_FLOAT;
- final Type SCALA_DOUBLE;
- final Type SCALA_CHAR;
- final Type SCALA_BOOLEAN;
- final Type SCALA_UNIT;
-
-// final Assembly VJSLIB;
-// final Assembly MSCORLIB;
-// final Assembly SCALA;
+ final Type BYTE;
+ final Type CHAR;
+ final Type SHORT;
+ final Type INT;
+ final Type LONG;
+ final Type FLOAT;
+ final Type DOUBLE;
+ final Type BOOLEAN;
+ final Type VOID;
+
+ final Type OBJECT;
+ final Type STRING;
+ final Type STRING_ARRAY;
+
+ final Type MONITOR;
+
+// static final MethodInfo CONCAT_OBJECT;
+// static final MethodInfo CONCAT_STRING_STRING;
+ final MethodInfo CONCAT_OBJECT_OBJECT;
+ final MethodInfo OBJECT_EQUALS;
+ final MethodInfo MONITOR_PULSE;
+ final MethodInfo MONITOR_PULSE_ALL;
+ final MethodInfo MONITOR_WAIT;
+ final MethodInfo MONITOR_WAIT_TIMEOUT;
+
+ Type SCALA_BYTE;
+ Type SCALA_SHORT;
+ Type SCALA_INT;
+ Type SCALA_LONG;
+ Type SCALA_FLOAT;
+ Type SCALA_DOUBLE;
+ Type SCALA_CHAR;
+ Type SCALA_BOOLEAN;
+ Type SCALA_UNIT;
+
+ FieldInfo RUNTIME_UNIT_VAL = null;
+
+ Symbol SYM_SUBSTRING_INT_INT;
+ MethodInfo SUBSTRING_INT_INT;
+ Symbol SYM_COMPARE_TO_IGNORE_CASE;
+ MethodInfo COMPARE_TO_IGNORE_CASE;
+
+ //##########################################################################
TypeCreator(GenMSIL gen, GenMSILPhase phase) {
this.gen = gen;
this.global = gen.global;
this.defs = global.definitions;
- Assembly.LoadFrom("/home/mihaylov/proj/msil/test/vjslib.dll").GetModules();
- Assembly.LoadFrom("/home/mihaylov/proj/vs.net/scala/bin/Debug/scala.dll").GetModules();
-
types2symbols = phase.types2symbols;
symbols2types = phase.symbols2types;
symbols2fields = phase.symbols2fields;
symbols2methods = phase.symbols2methods;
symbols2moduleFields = phase.symbols2moduleFields;
- map(defs.ANY_CLASS, SYSTEM_OBJECT);
- map(defs.ANYREF_CLASS, SYSTEM_OBJECT);
- map(defs.JAVA_OBJECT_CLASS, SYSTEM_OBJECT);
- map(defs.JAVA_STRING_CLASS, SYSTEM_STRING);
-
- translateMethod(defs.JAVA_OBJECT_CLASS, "equals",
- SYSTEM_OBJECT, "Equals");
- translateMethod(defs.JAVA_OBJECT_CLASS, "hashCode",
- SYSTEM_OBJECT, "GetHashCode");
- translateMethod(defs.JAVA_OBJECT_CLASS, "toString",
- SYSTEM_OBJECT, "ToString");
- translateMethod(defs.JAVA_OBJECT_CLASS, "finalize",
- SYSTEM_OBJECT, "Finalize");
-
- translateMethod(defs.JAVA_STRING_CLASS, "equals",
- SYSTEM_STRING, "Equals");
- translateMethod(defs.JAVA_STRING_CLASS, "toString",
- SYSTEM_STRING, "ToString");
- translateMethod(defs.JAVA_STRING_CLASS, "startsWith",
- SYSTEM_STRING, "StartsWith");
- translateMethod(defs.JAVA_STRING_CLASS, "length",
- SYSTEM_STRING, "get_Length");
- translateMethod(defs.JAVA_STRING_CLASS, "charAt",
- SYSTEM_STRING, "get_Chars");
- translateMethod(defs.JAVA_STRING_CLASS, "substring",
- SYSTEM_STRING, "Substring");
-
- //generate mappings for the methods of System.Threading.Monitor
- final Type[] OBJECT_1 = new Type[] {SYSTEM_OBJECT};
- final scalac.symtab.Type UNBOXED_LONG =
- new scalac.symtab.Type.UnboxedType(TypeTags.LONG);
- translateMethod(defs.JAVA_OBJECT_CLASS, "wait",
- scalac.symtab.Type.EMPTY_ARRAY,
- MONITOR, "Wait", OBJECT_1);
- translateMethod(defs.JAVA_OBJECT_CLASS, "wait",
- new scalac.symtab.
- Type[] {UNBOXED_LONG/*defs.LONG_TYPE*/},
- MONITOR, "Wait",
- new Type[] {SYSTEM_OBJECT, INT});
- translateMethod(defs.JAVA_OBJECT_CLASS, "notify",
- scalac.symtab.Type.EMPTY_ARRAY,
- MONITOR, "Pulse", OBJECT_1);
- translateMethod(defs.JAVA_OBJECT_CLASS, "notifyAll",
- scalac.symtab.Type.EMPTY_ARRAY,
- MONITOR, "PulseAll", OBJECT_1);
+ BYTE = Type.GetType("System.SByte");
+ CHAR = Type.GetType("System.Char");
+ SHORT = Type.GetType("System.Int16");
+ INT = Type.GetType("System.Int32");
+ LONG = Type.GetType("System.Int64");
+ FLOAT = Type.GetType("System.Single");
+ DOUBLE = Type.GetType("System.Double");
+ BOOLEAN = Type.GetType("System.Boolean");
+ VOID = Type.GetType("System.Void");
+
+ OBJECT = Type.GetType("System.Object");
+ STRING = Type.GetType("System.String");
+ STRING_ARRAY = Type.GetType("System.String[]");
+
+ MONITOR = Type.GetType("System.Threading.Monitor");
+
+ //CONCAT_OBJECT = STRING.GetMethod("Concat", new Type[] {OBJECT});
+ //CONCAT_STRING_STRING = STRING.GetMethod("Concat", new Type[] {STRING, STRING});
+ CONCAT_OBJECT_OBJECT =
+ STRING.GetMethod("Concat", new Type[] {OBJECT, OBJECT});
+ OBJECT_EQUALS = OBJECT.GetMethod("Equals", new Type[] {OBJECT});
+ MONITOR_PULSE = MONITOR.GetMethod("Pulse", new Type[] {OBJECT});
+ MONITOR_PULSE_ALL = MONITOR.GetMethod("PulseAll", new Type[] {OBJECT});
+ MONITOR_WAIT = MONITOR.GetMethod("Wait", new Type[] {OBJECT});
+ MONITOR_WAIT_TIMEOUT = MONITOR.GetMethod("Wait", new Type[] {OBJECT, INT});
+
+ Assembly.LoadFrom("/home/linuxsoft/apps/msil/vjslib.dll").GetModules();
+ Assembly.LoadFrom("/home/linuxsoft/apps/msil/scala.dll").GetModules();
+ Assembly.LoadFrom("/home/linuxsoft/apps/msil/scala_sc.dll").GetModules();
+ }
- final Type ObjectImpl = Type.GetType("com.ms.vjsharp.lang.ObjectImpl");
- //final MethodInfo getClass = ObjectImpl.GetMethod("getClass", OBJECT_1);
+ private boolean initialized = false;
+ void init() {
+ if (initialized)
+ return;
- translateMethod(defs.JAVA_OBJECT_CLASS, "getClass",
- scalac.symtab.Type.EMPTY_ARRAY,
- ObjectImpl, "getClass", OBJECT_1);
+ final Symbol JOBJECT = defs.JAVA_OBJECT_CLASS;
+ final Symbol JSTRING = defs.JAVA_STRING_CLASS;
SCALA_BYTE = getType("scala.Byte");
SCALA_SHORT = getType("scala.Short");
@@ -188,6 +161,90 @@ final class TypeCreator {
SCALA_BOOLEAN = getType("scala.Boolean");
SCALA_UNIT = getType("scala.Unit");
+ Type runtime = getType("scala.runtime.RunTime");
+ //System.out.println("scala.runtime.RunTime = " + runtime);
+ RUNTIME_UNIT_VAL = runtime.GetField("UNIT_VAL");
+
+ // initialize type mappings
+ map(defs.ANY_CLASS, OBJECT);
+ map(defs.ANYREF_CLASS, OBJECT);
+ map(JOBJECT, OBJECT);
+ map(JSTRING, STRING);
+
+ // constants useful for method mappings
+ final scalac.symtab.Type UNBOXED_LONG =
+ new scalac.symtab.Type.UnboxedType(TypeTags.LONG);
+ final scalac.symtab.Type UNBOXED_INT =
+ new scalac.symtab.Type.UnboxedType(TypeTags.INT);
+ final scalac.symtab.Type UNBOXED_CHAR =
+ new scalac.symtab.Type.UnboxedType(TypeTags.CHAR);
+
+ final scalac.symtab.Type[] jEmpty = scalac.symtab.Type.EMPTY_ARRAY;
+ final scalac.symtab.Type[] jString1 = new scalac.symtab.Type[]
+ {defs.STRING_TYPE()};
+ final scalac.symtab.Type[] jInt1 = new scalac.symtab.Type[]
+ {UNBOXED_INT};
+ final scalac.symtab.Type[] jInt2 = new scalac.symtab.Type[]
+ {UNBOXED_INT, UNBOXED_INT};
+ final scalac.symtab.Type[] jStringInt = new scalac.symtab.Type[]
+ {defs.STRING_TYPE(), UNBOXED_INT};
+ final scalac.symtab.Type[] jChar2 = new scalac.symtab.Type[]
+ {UNBOXED_CHAR, UNBOXED_CHAR};
+
+ final Type[] sObject1 = new Type[] {OBJECT};
+ final Type[] sString1 = new Type[] {STRING};
+ final Type[] sString2 = new Type[] {STRING, STRING};
+ final Type[] sChar1 = new Type[] {CHAR};
+ final Type[] sCharInt2 = new Type[] {CHAR, INT};
+
+ final Type ObjectImpl = Type.GetType("com.ms.vjsharp.lang.ObjectImpl");
+
+ // map methods of java.lang.Object
+ translateMethod(JOBJECT, "equals", OBJECT, "Equals");
+ translateMethod(JOBJECT, "hashCode", OBJECT, "GetHashCode");
+ translateMethod(JOBJECT, "toString", OBJECT, "ToString");
+ translateMethod(JOBJECT, "finalize", OBJECT, "Finalize");
+ translateMethod(JOBJECT, "wait", jEmpty, MONITOR, "Wait", sObject1);
+ translateMethod(JOBJECT, "wait", new scalac.symtab.
+ Type[] {UNBOXED_LONG}, // defs.LONG_TYPE
+ MONITOR, "Wait",
+ new Type[] {OBJECT, INT});
+ translateMethod(JOBJECT, "notify", jEmpty, MONITOR, "Pulse", sObject1);
+ translateMethod(JOBJECT, "notifyAll", jEmpty, MONITOR, "PulseAll", sObject1);
+ translateMethod(JOBJECT, "getClass", jEmpty, ObjectImpl, "getClass", sObject1);
+
+ // map methods of java.lang.String
+ translateMethod(JSTRING, "equals", STRING, "Equals");
+ translateMethod(JSTRING, "toString", STRING, "ToString");
+ translateMethod(JSTRING, "compareTo", STRING, "CompareTo");
+ translateMethod(JSTRING, "length", STRING, "get_Length");
+ translateMethod(JSTRING, "charAt", STRING, "get_Chars");
+ translateMethod(JSTRING, "concat", jString1, STRING, "Concat", sString2);
+ translateMethod(JSTRING, "indexOf", jInt1, STRING, "IndexOf", sChar1);
+ translateMethod(JSTRING, "indexOf", jInt2, STRING, "IndexOf", sCharInt2);
+ translateMethod(JSTRING, "indexOf", jString1, STRING, "IndexOf");
+ translateMethod(JSTRING, "indexOf", jStringInt, STRING, "IndexOf");
+ translateMethod(JSTRING, "lastIndexOf", jInt1, STRING, "LastIndexOf", sChar1);
+ translateMethod(JSTRING, "lastIndexOf", jInt2, STRING, "LastIndexOf", sCharInt2);
+ translateMethod(JSTRING, "lastIndexOf", jString1, STRING, "LastIndexOf");
+ translateMethod(JSTRING, "lastIndexOf", jStringInt, STRING, "LastIndexOf");
+ translateMethod(JSTRING, "toLowerCase", jEmpty, STRING, "ToLower");
+ translateMethod(JSTRING, "toUpperCase", jEmpty, STRING, "ToUpper");
+ translateMethod(JSTRING, "startsWith", jString1, STRING, "StartsWith");
+ translateMethod(JSTRING, "endsWith", jString1, STRING, "EndsWith");
+ translateMethod(JSTRING, "substring", jInt1, STRING, "Substring");
+ translateMethod(JSTRING, "intern", jEmpty, STRING, "Intern", sString1);
+ translateMethod(JSTRING, "replace", jChar2, STRING, "Replace");
+ translateMethod(JSTRING, "toCharArray", STRING, "ToCharArray");
+
+ SYM_SUBSTRING_INT_INT = lookupMethod(JSTRING, "substring", jInt2);
+ SUBSTRING_INT_INT =
+ STRING.GetMethod("Substring", new Type[]{INT,INT});
+ SYM_COMPARE_TO_IGNORE_CASE =
+ lookupMethod(JSTRING, "compareToIgnoreCase", jString1);
+ COMPARE_TO_IGNORE_CASE =
+ STRING.GetMethod("Compare", new Type[]{STRING, STRING, BOOLEAN});
+ initialized = true;
}
// looks up a method according to the signature
@@ -196,32 +253,14 @@ final class TypeCreator {
{
Symbol[] methods = clazz.members().
lookup(Name.fromString(name)).alternativeSymbols();
-
-// System.out.print("lookupMethod: Trying to match method " + name + "(");
-// for (int i = 0; i < paramTypes.length; i++) {
-// if (i > 0) System.out.print(", ");
-// System.out.print(paramTypes[i]);
-// }
-// System.out.println(")");
-// System.out.println("against members of class " + clazz + ":");
-
search:
for (int i = 0; i < methods.length; i++) {
-// System.out.print(Debug.show(methods[i]));
switch (methods[i].info()) {
case MethodType(Symbol[] vparams, _):
-// System.out.print("(");
-// for (int j = 0; j < vparams.length; j++) {
-// if (j > 0) System.out.print(", ");
-// System.out.print(vparams[j] + ": "
-// + Debug.show(vparams[j].info()));
-// }
-// System.out.println("): " + Debug.show(methods[i].info()));
-
if (paramTypes.length != vparams.length)
continue;
for (int j = 0; j < vparams.length; j++) {
- if (!paramTypes[j].equals(vparams[j].info()))
+ if (!paramTypes[j].isSameAs(vparams[j].info()))
continue search;
}
return methods[i];
@@ -230,9 +269,55 @@ final class TypeCreator {
}
}
return null;
+ } // Symbol lookupMethod(...)
+
+ static String methodSignature(Symbol sym) {
+ switch (sym.info()) {
+ case MethodType(Symbol[] vparams, scalac.symtab.Type result):
+ StringBuffer s = new StringBuffer();
+ s.append(result); s.append(' ');
+ s.append(Debug.show(sym.owner())); s.append('.');
+ s.append(sym.name.toString()); s.append('(');
+ for (int i = 0; i < vparams.length; i++) {
+ if (i > 0) s.append(", ");
+ //s.append(Debug.show(vparams[i].info()));
+ s.append(vparams[i].info());
+ }
+ s.append(")");
+ return s.toString();
+ default:
+ return "Symbol doesn't have a method type: " + dumpSym(sym);
+ }
+ }
+
+ String paramList(scalac.symtab.Type[] paramTypes) {
+ if (paramTypes.length == 0)
+ return "()";
+ StringBuffer s = new StringBuffer("(");
+ for (int i = 0; i < paramTypes.length; i++) {
+ if (i > 0)
+ s.append(", ");
+ s.append(paramTypes[i]);
+ }
+ s.append(")");
+ return s.toString();
+ }
+
+ /**
+ * Create a mapping from method with symbol 'sym'
+ * to the method newClazz.newName(params)
+ */
+ void mapMethod(Symbol sym, Type newClazz, String name, Type[] params) {
+ MethodInfo method = newClazz.GetMethod(name, params);
+ assert method != null : "Cannot find translation for: "
+ + methodSignature(sym);
+ symbols2methods.put(sym, method);
+ //log("translateMethod: " + methodSignature(sym) + " -> " + method);
}
- // create mapping between the specified two methods only
+ /**
+ * create mapping between the specified two methods only
+ */
void translateMethod(Symbol clazz, String name,
scalac.symtab.Type[] paramTypes,
Type newClazz, String newName, Type[] newParamTypes)
@@ -240,14 +325,13 @@ final class TypeCreator {
Symbol sym = lookupMethod(clazz, name, paramTypes);
assert sym != null : "Cannot find method: " + name + " in class " +
dumpSym(clazz);
- //System.out.println("translate2staticMethod:");
- //System.out.println("\told method: " + dumpSym(sym));
- MethodInfo method = newClazz.GetMethod(newName, newParamTypes);
- symbols2methods.put(sym, method);
- //System.out.println("\tnew method: " + method);
+ mapMethod(sym, newClazz, newName, newParamTypes);
}
- // look up the method and then create the mapping
+ /**
+ * Lookup the method and create mapping for all overloaded alternatives
+ * to the corresponding methods in 'newClazz'
+ */
void translateMethod(Symbol clazz, String name,
Type newClazz, String newName)
{
@@ -256,6 +340,19 @@ final class TypeCreator {
translateMethod(sym, newClazz, newName);
}
+ /**
+ */
+ void translateMethod(Symbol clazz, String name,
+ scalac.symtab.Type[] paramTypes,
+ Type newClazz, String newName)
+ {
+ Type[] newParamTypes = new Type[paramTypes.length];
+ for (int i = 0; i < paramTypes.length; i++)
+ newParamTypes[i] = getType(paramTypes[i]);
+ translateMethod(clazz, name, paramTypes,
+ newClazz, newName, newParamTypes);
+ }
+
// create a mapping for the two methods
void translateMethod(Symbol sym, Type newClazz, String newName) {
switch (sym.info()) {
@@ -263,8 +360,7 @@ final class TypeCreator {
Type[] params = new Type[vparams.length];
for (int i = 0; i < params.length; i++)
params[i] = getType(vparams[i]);
- MethodInfo method = newClazz.GetMethod(newName, params);
- symbols2methods.put(sym, method);
+ mapMethod(sym, newClazz, newName, params);
break;
case OverloadedType(Symbol[] alts, _):
for (int i = 0; i < alts.length; i++)
@@ -275,7 +371,6 @@ final class TypeCreator {
}
}
-
/** Finilizes ('bakes') the newly created types
*/
public void createTypes() {
@@ -285,7 +380,9 @@ final class TypeCreator {
}
- // creates bidirectional mapping from symbols to types
+ /**
+ * creates bidirectional mapping from symbols to types
+ */
public void map(Symbol sym, Type type) {
symbols2types.put(sym, type);
if (sym.isClass())
@@ -296,6 +393,13 @@ final class TypeCreator {
return (Symbol) types2symbols.get(t);
}
+ /**
+ * Return the System.Type object with the given name
+ */
+ Type getType(String name) {
+ return Type.GetType(name);
+ }
+
// public Type getType(Symbol sym) {
// Type type = null;
// try { type = getType2(sym); }
@@ -310,13 +414,6 @@ final class TypeCreator {
/**
- * Return the System.Type object with the given name
- */
- Type getType(String name) {
- return Type.GetType(name);
- }
-
- /**
* Return the System.Type object corresponding to the type of the symbol
*/
Type getType(Symbol sym) {
@@ -324,49 +421,88 @@ final class TypeCreator {
Type type = (Type) symbols2types.get(sym);
if (type != null)
return type;
- if (sym.isJava())
+ if (sym.isJava()) {
+// if (sym.isExternal()) {
type = getType(sym.fullNameString());
- else {
+ }
+ if (type == null) {
+ final Symbol owner = sym.owner();
switch (sym.info()) {
case CompoundType(_, _):
- String fullname = sym.type().symbol().fullNameString() +
- (sym.isModuleClass() ? "$" : "");;
-
- type = Type.GetType(fullname);
+ if (sym.owner().isClass()) {
+ Type outer = getType(sym.owner());
+ if (outer == null)
+ throw new RuntimeException("Cannot find type: "
+ + dumpSym(owner));
+ type = (Type) symbols2types.get(sym);
+ if (type != null)
+ return type;
+ if (outer instanceof TypeBuilder)
+ return createType(sym);
+ String name = sym.nameString()
+ + (sym.isModuleClass() ? "$" : "");
+ //log("getType: looking up nested type " + outer + "." + name);
+ type = outer.GetNestedType(name);
+ } else {
+ String fullname = sym.type().symbol().fullNameString() +
+ (sym.isModuleClass() ? "$" : "");
+ type = getType(fullname);
+ }
if (type == null)
type = createType(sym);
break;
case UnboxedArrayType(scalac.symtab.Type elemtp):
-// // force the creation of the type
-// log("UnboxedArrayType: " + elemtp + "[]");
-// getType(elemtp.symbol());
-// Type t = Type.GetType(elemtp + "[]");
-// log("Array type: " + t);
-// return t;
- type = getTypeFromType(sym.info());
+ type = getType(sym.info());
break;
default:
//log("getType: Going through the type: " + dumpSym(sym));
- type = getTypeFromType(sym.type());
+ type = getType(sym.info());
}
}
assert type != null : "Unable to find type: " + dumpSym(sym);
+ //log("getType(): type = " + type);
map(sym, type);
return type;
}
+ /** Retrieve the MSIL Type from the scala type
+ */
+ public Type getType(scalac.symtab.Type type) {
+ //log("getType: " + Debug.show(type));
+ switch (type) {
+ case CompoundType(_, _):
+ return getType(type.symbol());
+
+ case UnboxedType(int kind):
+ return getTypeFromKind(kind);
+
+ case TypeRef(_, Symbol s, _):
+ return getType(s);
+
+ case UnboxedArrayType(scalac.symtab.Type elemtp):
+ // force the creation of the type
+ return Type.GetType(getType(elemtp) + "[]");
+ case NoType:
+ return VOID;
+
+ default:
+ global.fail("getType: " + Debug.show(type));
+ }
+ return null;
+ }
+
/** Creates a TypeBuilder object corresponding to the symbol
*/
- public TypeBuilder createType(Symbol sym) {
- TypeBuilder type = (TypeBuilder)symbols2types.get(sym);
+ public Type createType(Symbol sym) {
+ Type type = (Type)symbols2types.get(sym);
assert type == null : "Type " + type +
" already defined for symbol: " + dumpSym(sym);
- //log("TypeCreator.getType: creating type for " + dumpSym(sym));
+ //log("TypeCreator.createType(): creating type for " + dumpSym(sym));
final Symbol owner = sym.owner();
final String typeName =
(owner.isClass() ? sym.nameString() : sym.fullNameString()) +
@@ -374,16 +510,12 @@ final class TypeCreator {
final ModuleBuilder module = gen.currModule;
final scalac.symtab.Type classType = sym.info();
-
- //log("createType: " + dumpSym(sym) + "\n");
switch (classType) {
case CompoundType(scalac.symtab.Type[] baseTypes, _):
Type superType = null;
Type[] interfaces = null;
int inum = baseTypes.length;
if (sym.isInterface()) {
-// log("interface " + sym.fullNameString() +
-// " extends " + dumpSym(baseTypes[0].symbol()));
int baseIndex = 0;
if (baseTypes[0].symbol() == defs.ANY_CLASS) {
--inum;
@@ -402,8 +534,7 @@ final class TypeCreator {
interfaces[i - 1] = getType(baseTypes[i].symbol());
}
- // i.e. top level class
- if (owner.isRoot() || owner.isPackage()) {
+ if (owner.isRoot() || owner.isPackage()) { // i.e. top level class
// log("createType():");
// log("\ttypeName = " + typeName);
// log("\tsuperType = " + superType);
@@ -414,12 +545,17 @@ final class TypeCreator {
(typeName, translateTypeAttributes(sym.flags, false),
superType, interfaces);
} else {
- final Type oT = getType(owner);
- //log("createType: owner type = " + oT);
- final TypeBuilder outerType = (TypeBuilder) getType(owner);
- type = outerType.DefineNestedType
- (typeName, translateTypeAttributes(sym.flags, true),
- superType, interfaces);
+ final Type outerType = (Type) getType(owner);
+ // check if the type have not been created by
+ // the (possible) creation of the outer type
+ type = (Type) symbols2types.get(sym);
+ if (type != null)
+ return type;
+ if (outerType instanceof TypeBuilder)
+ type = ((TypeBuilder)outerType).DefineNestedType
+ (typeName, translateTypeAttributes(sym.flags, true),
+ superType, interfaces);
+ else return outerType.GetNestedType(typeName);
}
break;
@@ -429,26 +565,23 @@ final class TypeCreator {
}
typeBuilders.add(type);
map(sym, type);
- //log("createType: " + dumpSym(sym) + " => " + type.getSignature());
- //log("createType: symbol type symbol = " +
- //getTypeFromType(sym.type()).getSignature());
- // create the members of the class
+ // create the members of the class but not nested classes
+ // they will be created when the tree is being traversed (at latest)
for (Scope.SymbolIterator syms = sym.members().iterator();
syms.hasNext(); )
{
Symbol[] members = syms.next().alternativeSymbols();
for (int i = 0; i < members.length; i++) {
-// System.out.println("\t" + dumpSym(members[i]));
- if (members[i].isClass()) {
- getType(members[i]);
- } else if (members[i].isMethod() /*&& !members[i].isModule()*/) {
+ if (members[i].isMethod() /*&& !members[i].isModule()*/) {
createMethod(members[i]);
}
- else if (!members[i].isClass() &&
- !members[i].isModule()) {
- createField(members[i]);
- }
+ else if (!members[i].isClass()
+ && !members[i].isModule()
+ && !members[i].isType())
+ {
+ createField(members[i]);
+ }
}
}
@@ -456,11 +589,10 @@ final class TypeCreator {
Set m = collapseInterfaceMethods(classType);
for (Iterator i = m.iterator(); i.hasNext(); ) {
Symbol s = (Symbol) i.next();
- Symbol method = lookupMethodImplementation(classType, s);
- if (method == Symbol.NONE) {
- log("Creating method: " +
- createMethod(type, s.name, s.info(),
- s.flags | Modifiers.DEFERRED));
+ Symbol methodSym = lookupMethodImplementation(classType, s);
+ if (methodSym == Symbol.NONE) {
+ MethodBase method = createMethod
+ ((TypeBuilder)type, s.name, s.info(), s.flags | Modifiers.DEFERRED);
}
}
}
@@ -491,7 +623,7 @@ final class TypeCreator {
Symbol[] methods = method.alternativeSymbols();
for (int i = 0; i < methods.length; i++) {
//log("\t" + Debug.show(methods[i]) + ": " + methods[i].info());
- if (methods[i].info().equals(sym.info())) {
+ if (methods[i].info().isSameAs(sym.info())) {
//log("\t\t^ Found ^");
return methods[i];
}
@@ -539,57 +671,32 @@ final class TypeCreator {
}
- /** Retrieve the MSIL Type from the scala type
- */
- public Type getTypeFromType(scalac.symtab.Type type) {
- //log("getTypeFromType: " + Debug.show(type));
- switch (type) {
- case CompoundType(_, _):
- return getType(type.symbol());
-
- case UnboxedType(int kind):
- return getTypeFromKind(kind);
-
- case TypeRef(_, Symbol s, _):
- return getType(s);
-
- case UnboxedArrayType(scalac.symtab.Type elemtp):
- // force the creation of the type
- //log("UnboxedArrayType: " + elemtp + "[]");
- return Type.GetType(getTypeFromType(elemtp) + "[]");
- case NoType:
- return VOID;
-
- default:
- global.fail("getTypeFromType: " + Debug.show(type));
- }
- return null;
- }
-
-
+ /***/
public MethodBase getMethod(Symbol sym) {
MethodBase method = null;
try {
method = getMethod2(sym);
} catch (Exception e) {
logErr("getMethod: " + dumpSym(sym));
- if (global.debug) e.printStackTrace();
+ e.printStackTrace();
}
return method;
}
+ final int ALL_DECLARED = BindingFlags.Instance | BindingFlags. Static
+ | BindingFlags.Public | BindingFlags.DeclaredOnly;
/** Returns the MethodBase object corresponding to the symbol
*/
public MethodBase getMethod2(Symbol sym) {
// force the creation of the declaring type
- getType(sym.owner());
+ Type owner = getType(sym.owner());
MethodBase method = (MethodBase) symbols2methods.get(sym);
if (method != null)
return method;
-
-// System.err.println("getMethod: resolving " + dumpSym(sym));
-// System.err.println("getMethod: sym.owner() = " + dumpSym(sym.owner()));
+ //System.err.println("getMethod2: resolving " + dumpSym(sym));
+ //System.err.println("getMethod2: sym.owner() = " + dumpSym(sym.owner()));
+ //System.err.println("getMethod2: method owner = " + owner);
switch (sym.info()) {
case MethodType(Symbol[] vparams, scalac.symtab.Type result):
Type[] params = new Type[vparams.length];
@@ -614,16 +721,16 @@ final class TypeCreator {
default:
global.fail("Symbol doesn't have a method type: " + Debug.show(sym));
}
- if (method == null) {
- Type owner = getType(sym.owner());
- log("Methods of class " + owner);
- MethodInfo[] methods = owner.GetMethods();
- for (int i = 0; i < methods.length; i++)
- log("\t" + methods[i]);
- }
- assert method != null : "Cannot find method: " + dumpSym(sym);
+// if (method == null) {
+// Type owner = getType(sym.owner());
+// log("Methods of class " + owner);
+// MethodInfo[] methods = owner.GetMethods(ALL_DECLARED);
+// for (int i = 0; i < methods.length; i++)
+// log("\t" + methods[i]);
+// }
+ assert method != null : "Cannot find method: " + methodSignature(sym);
symbols2methods.put(sym, method);
- //log("method found: " + method);
+ //log("getMethod2: method found: " + method);
return method;
}
@@ -656,9 +763,11 @@ final class TypeCreator {
else if (name == Names.hashCode) sname = "GetHashCode";
else sname = name.toString();
+// if (type.IsInterface)
+// flags |= Modifiers.DEFERRED;
MethodBuilder methodBuilder = type.DefineMethod
(sname, translateMethodAttributes(flags, false),
- getTypeFromType(result), params);
+ getType(result), params);
for (int i = 0; i < vparams.length; i++)
methodBuilder.DefineParameter
@@ -684,7 +793,9 @@ final class TypeCreator {
switch (sym.info()) {
case MethodType(Symbol[] vparams, scalac.symtab.Type result):
if (sym.isInitializer()) {
- TypeBuilder type = (TypeBuilder) getTypeFromType(result);
+ //log("constructor symbol: " + dumpSym(sym));
+ //TypeBuilder type = (TypeBuilder) getType(result);
+ TypeBuilder type = (TypeBuilder) getType(sym.owner());
method = createMethod(type, sym.name, sym.info(), sym.flags);
} else {
int flags = ( owner.isJava() && owner.isModuleClass() ) ?
@@ -730,8 +841,7 @@ final class TypeCreator {
TypeBuilder owner = (TypeBuilder) getType(sym.owner());
int flags = ( sym.owner().isJava() && sym.owner().isModuleClass() ) ?
sym.flags | Modifiers.STATIC : sym.flags;
- field = owner.DefineField(sym.name.toString(),
- getTypeFromType(sym.type()),
+ field = owner.DefineField(sym.name.toString(), getType(sym.type()),
translateFieldAttributes(flags));
Object o = symbols2fields.put(sym, field);
assert o == null : "Cannot re-define field: " + dumpSym(sym);
@@ -759,6 +869,7 @@ final class TypeCreator {
/**
+ * @return the field descriptor of the object instance
*/
FieldInfo getModuleField(Symbol sym) {
FieldInfo moduleField = null;
@@ -772,6 +883,11 @@ final class TypeCreator {
if (sym != s) {
//log("getModuleField: going through: " + dumpSym(s));
moduleField = getModuleField(s);
+ } else if (sym.isExternal()){
+ Type t = getType(sym);
+ assert !(t instanceof TypeBuilder);
+ moduleField = t.GetField(MODULE_S);
+ assert moduleField != null;
} else {
Type t = getType(sym);
assert t instanceof TypeBuilder :
@@ -875,7 +991,7 @@ final class TypeCreator {
/** Retrieves the primitive datatypes given their kind
*/
- public static Type getTypeFromKind(int kind) {
+ final Type getTypeFromKind(int kind) {
switch (kind) {
case TypeTags.CHAR: return CHAR;
case TypeTags.BYTE: return BYTE;
@@ -886,7 +1002,7 @@ final class TypeCreator {
case TypeTags.DOUBLE: return DOUBLE;
case TypeTags.BOOLEAN: return BOOLEAN;
case TypeTags.UNIT: return VOID;
- case TypeTags.STRING: return SYSTEM_STRING;
+ case TypeTags.STRING: return STRING;
default:
throw new ApplicationError("Unknown kind: " + kind);
}