summaryrefslogtreecommitdiff
path: root/sources/scalac/backend
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2003-08-22 15:45:50 +0000
committermihaylov <mihaylov@epfl.ch>2003-08-22 15:45:50 +0000
commitdc2dd01c6d3e6cd03cf5bca15ad2c43a62bd2906 (patch)
treec79e74042b52746b7a46eecdd5c281ea06701405 /sources/scalac/backend
parent20543e16068c45d32647bfb5c56ce9f06ab921d5 (diff)
downloadscala-dc2dd01c6d3e6cd03cf5bca15ad2c43a62bd2906.tar.gz
scala-dc2dd01c6d3e6cd03cf5bca15ad2c43a62bd2906.tar.bz2
scala-dc2dd01c6d3e6cd03cf5bca15ad2c43a62bd2906.zip
- extract information solely from symbols - doe...
- extract information solely from symbols - doesn't traverse the tree - creates abstract method definitions for classes that do not implement certain interface methods (required by the .NET CLR) - minor code cleanups
Diffstat (limited to 'sources/scalac/backend')
-rw-r--r--sources/scalac/backend/msil/TypeCreator.java304
1 files changed, 197 insertions, 107 deletions
diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java
index faca45a182..2e56853b13 100644
--- a/sources/scalac/backend/msil/TypeCreator.java
+++ b/sources/scalac/backend/msil/TypeCreator.java
@@ -31,10 +31,18 @@ import ch.epfl.lamp.util.Position;
import java.util.Map;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.Set;
+import java.util.LinkedHashSet;
-public final class TypeCreator
- extends scalac.ast.Traverser
-{
+/**
+ * Creates System.Reflection objects corresponding to
+ * Scala symbols
+ *
+ * @author Nikolay Mihaylov
+ * @version 1.1
+ */
+
+public final class TypeCreator {
final private GenMSIL gen;
final private Global global;
@@ -151,7 +159,7 @@ public final class TypeCreator
MONITOR, "Wait", OBJECT_1);
translateMethod(defs.JAVA_OBJECT_CLASS, "wait",
new scalac.symtab.
- Type[] {UNBOXED_LONG},
+ Type[] {defs.LONG_TYPE},
MONITOR, "Wait",
new Type[] {SYSTEM_OBJECT, INT});
translateMethod(defs.JAVA_OBJECT_CLASS, "notify",
@@ -176,6 +184,7 @@ public final class TypeCreator
{
Symbol[] methods = clazz.members().
lookup(Name.fromString(name)).alternativeSymbols();
+
search:
for (int i = 0; i < methods.length; i++) {
switch (methods[i].info()) {
@@ -200,7 +209,8 @@ public final class TypeCreator
Type newClazz, String newName, Type[] newParamTypes)
{
Symbol sym = lookupMethod(clazz, name, paramTypes);
- assert sym != null : "Cannot find method: " + name;
+ 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);
@@ -236,59 +246,9 @@ public final class TypeCreator
}
}
- public void traverse(Unit[] units) {
- for (int i = 0; i < units.length; i++) {
- unit = units[i];
- traverse(unit);
- }
- }
-
- private Symbol currentClass;
-
- public void traverse(Tree tree) {
- pos = tree.pos;
- final Symbol sym = tree.hasSymbol() ? tree.symbol() : null;
- switch (tree) {
- case ClassDef(_, _, _, _, _, Template(_, Tree[] body)):
- Symbol tmpClass = currentClass;
- currentClass = sym;
- TypeBuilder tb = (TypeBuilder) symbols2types.get(sym);
- if (tb != null) {
- assert tb == null || (tb instanceof TypeBuilder);
- //logErr("Class already defined: " + dumpSym(sym) +
- // ";old type: " + tb);
- } else {
- tb = (TypeBuilder) createType(sym);
- }
- types2symbols.put(tb, sym);
- traverse(body);
- currentClass = tmpClass;
- break;
-
- case ValDef(_, _, _, _):
- if (currentClass == null)
- break;
- FieldBuilder field = (FieldBuilder) symbols2fields.get(sym);
- if (field != null)
- logErr("Field already defined: " + dumpSym(sym));
- else {
- field = (FieldBuilder) createField(sym);
- }
- break;
-
- case DefDef(_, _, _, _, _, _):
- MethodBase method = (MethodBase) symbols2methods.get(sym);
- if (method != null)
- logErr("Method already defined: " + dumpSym(sym));
- else
- method = createMethod(sym);
- break;
-
- default:
- super.traverse(tree);
- }
- }
+ /** Finilizes ('bakes') the newly created types
+ */
public void createTypes() {
Iterator iter = typeBuilders.iterator();
while (iter.hasNext())
@@ -296,6 +256,7 @@ public final class TypeCreator
}
+ // creates bidirectional mapping from symbols to types
public void map(Symbol sym, Type type) {
symbols2types.put(sym, type);
if (sym.isClass())
@@ -326,16 +287,8 @@ public final class TypeCreator
Type type = (Type) symbols2types.get(sym);
if (type != null)
return type;
- if (sym.isJava()) {
- //log("getType: looking up Java class: " + dumpSym(sym));
-// try {
-// type = JavaType.fromString(sym.fullNameString());
-// } catch (ClassNotFoundException e) {
-// global.fail(formatMessage("Cannot find class: " +
-// sym.fullNameString()));
-// }
+ if (sym.isJava())
type = getJavaType(sym.fullNameString());
- }
else {
switch (sym.info()) {
case CompoundType(_, _):
@@ -375,14 +328,18 @@ public final class TypeCreator
assert type == null : "Type " + type +
" already defined for symbol: " + dumpSym(sym);
+
//log("TypeCreator.getType: creating type for " + dumpSym(sym));
final Symbol owner = sym.owner();
final String typeName =
(owner.isClass() ? sym.nameString() : sym.fullNameString()) +
(sym.isModuleClass() ? "$" : "");
final ModuleBuilder module = gen.currModule;
+
+ final scalac.symtab.Type classType = sym.info();
+
//log("createType: " + dumpSym(sym) + "\n");
- switch (sym.info()) {
+ switch (classType) {
case CompoundType(scalac.symtab.Type[] baseTypes, _):
Type superType = null;
Type[] interfaces = null;
@@ -438,11 +395,107 @@ public final class TypeCreator
//log("createType: " + dumpSym(sym) + " => " + type.getSignature());
//log("createType: symbol type symbol = " +
//getTypeFromType(sym.type()).getSignature());
+
+ // create the members of the class
+ for (Scope.SymbolIterator syms = sym.members().iterator();
+ syms.hasNext(); )
+ {
+ Symbol[] members = syms.next().alternativeSymbols();
+ for (int i = 0; i < members.length; i++) {
+ if (members[i].isClass()) {
+ getType(members[i]);
+ } else if (members[i].isMethod() /*&& !members[i].isModule()*/) {
+ createMethod(members[i]);
+ }
+ else if (!members[i].isClass() &&
+ !members[i].isModule()) {
+ createField(members[i]);
+ }
+ }
+ }
+
+ if (!sym.isInterface()) {
+ 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) {
+ createMethod(type, s.name, s.info(),
+ s.flags | Modifiers.DEFERRED);
+ }
+ }
+ }
+
return type;
+ } // createType()
+
+
+
+// Set collapseInheritedMethods(scalac.symtab.Type classType){
+// LinkedHashSet methods = new LinkedHashSet();
+// scalac.symtab.Type[] parents = classType.parents();
+// if (parents.length > 0) {
+// methods.addAll(collapseInheritedMethods(parents[0]));
+// }
+// methods.addAll(expandScopeMethods(methods, classType.members()));
+// return methods;
+// }
+
+
+ /**
+ */
+ Symbol lookupMethodImplementation(scalac.symtab.Type classType, Symbol sym) {
+ Symbol method = classType.members().lookup(sym.name);
+ Symbol[] methods = method.alternativeSymbols();
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].info().equals(sym.info()))
+ return methods[i];
+ }
+
+ scalac.symtab.Type[] parents = classType.parents();
+ if (parents.length > 0) {
+ // look up the inheritance chain
+ method = lookupMethodImplementation(parents[0], sym);
+ } else {
+ return Symbol.NONE;
+ }
+
+ // if the method is private this guarantees that there isn't
+ // public method with such name up the chain
+ return method.isPrivate() ? Symbol.NONE : method;
}
+
+ /** returns a set with the symbols of all the methods from
+ * all interfaces implemented by the class
+ */
+ Set collapseInterfaceMethods(scalac.symtab.Type classType) {
+ LinkedHashSet methods = new LinkedHashSet();
+ scalac.symtab.Type[] parents = classType.parents();
+ for (int i = 1; i < parents.length; i++) {
+ methods.addAll(collapseInterfaceMethods(parents[i]));
+ }
+ methods.addAll(expandScopeMethods(methods, classType.members()));
+ return methods;
+ }
+
+
/**
*/
+ Set expandScopeMethods(Set symbols, Scope scope) {
+ for(Scope.SymbolIterator syms = scope.iterator(); syms.hasNext(); ) {
+ Symbol[] members = syms.next().alternativeSymbols();
+ for (int i = 0; i < members.length; i++) {
+ if (members[i].isMethod())
+ symbols.add(members[i]);
+ }
+ }
+ return symbols;
+ }
+
+
+ /** Retrieve the MSIL Type from the scala type
+ */
public Type getTypeFromType(scalac.symtab.Type type) {
//log("getTypeFromType: " + Debug.show(type));
switch (type) {
@@ -468,23 +521,27 @@ public final class TypeCreator
return null;
}
+
public MethodBase getMethod(Symbol sym) {
MethodBase method = null;
try {
method = getMethod2(sym);
- } catch (ClassCastException e) {
+ } catch (Exception e) {
logErr("getMethod: " + dumpSym(sym));
if (global.debug) e.printStackTrace();
}
return method;
}
+
/** Returns the MethodBase object corresponding to the symbol
*/
public MethodBase getMethod2(Symbol sym) {
MethodBase method = (MethodBase) symbols2methods.get(sym);
if (method != null)
return method;
+
+
//log("getMethod: resolving " + dumpSym(sym));
//log("getMethod: sym.owner() = " + dumpSym(sym.owner()));
switch (sym.info()) {
@@ -492,7 +549,7 @@ public final class TypeCreator
Type[] params = new Type[vparams.length];
for (int i = 0; i < params.length; i++)
params[i] = getType(vparams[i]);
-// if ( sym.isConstructor() ) {
+ //if ( sym.isConstructor() ) {
if (sym.name == Names.CONSTRUCTOR) {
// The owner of a constructor is the outer class
// so get the result type of the constructor
@@ -525,6 +582,7 @@ public final class TypeCreator
return method;
}
+
MethodBase createMethod(Symbol sym) {
MethodBase method = null;
try {
@@ -537,51 +595,72 @@ public final class TypeCreator
return method;
}
- MethodBase createMethod2(Symbol sym) {
- final Symbol owner = sym.owner();
+
+ /**
+ */
+ MethodBase createMethod(TypeBuilder type, Name name,
+ scalac.symtab.Type symType, int flags)
+ {
MethodBase method = null;
- //log("createMethod: resolving " + dumpSym(sym));
- //log("createMethod: sym.owner() = " + dumpSym(sym.owner()));
- switch (sym.info()) {
+ switch (symType) {
case MethodType(Symbol[] vparams, scalac.symtab.Type result):
Type[] params = new Type[vparams.length];
for (int i = 0; i < params.length; i++)
params[i] = getType(vparams[i]);
- int flags = ( owner.isJava() && owner.isModuleClass() ) ?
- sym.flags | Modifiers.STATIC :
- sym.flags;
-
-// if (sym.isConstructor()) {
- if (sym.name == Names.CONSTRUCTOR) {
- Type type = getTypeFromType(result);
- ConstructorBuilder constructor =
- ((TypeBuilder)type).DefineConstructor
+ if (name == Names.CONSTRUCTOR) {
+ ConstructorBuilder constructor = type.DefineConstructor
(translateMethodAttributes(flags, true),
- CallingConventions.Standard,
- params);
+ CallingConventions.Standard, params);
+
for (int i = 0; i < vparams.length; i++)
constructor.DefineParameter
(i, ParameterAttributes.In, vparams[i].name.toString());
method = constructor;
} else {
- String name = sym.name.toString();
- if (sym.name == Names.toString) name = "ToString";
- else if (sym.name == Names.hashCode) name = "GetHashCode";
- else if (sym.name == Names.equals) name = "Equals";
- Type type = getType(owner);
- //log("createMethod: Define method for " + dumpSym(sym));
- MethodBuilder methodBuilder =
- ((TypeBuilder)type).DefineMethod
- (name, translateMethodAttributes(flags, false),
+ String sname;
+ if (name == Names.toString) sname = "ToString";
+ else if (name == Names.equals) sname = "Equals";
+ else if (name == Names.hashCode) sname = "GetHashCode";
+ else sname = name.toString();
+
+ MethodBuilder methodBuilder = type.DefineMethod
+ (sname, translateMethodAttributes(flags, false),
getTypeFromType(result), params);
+
for (int i = 0; i < vparams.length; i++)
methodBuilder.DefineParameter
- (i, ParameterAttributes.In,
- vparams[i].name.toString());
+ (i, ParameterAttributes.In, vparams[i].name.toString());
method = methodBuilder;
- //log("createMethod: New method defined: " +
- //method.getSignature());
+ }
+ break;
+ default:
+ assert false : "Method type expected: " + Debug.show(symType);
+ }
+
+ return method;
+ }
+
+
+ /** create the method corresponding to the symbol
+ */
+ MethodBase createMethod2(Symbol sym) {
+ final Symbol owner = sym.owner();
+ MethodBase method = null;
+ //log("createMethod: resolving " + dumpSym(sym));
+ //log("createMethod: sym.owner() = " + dumpSym(sym.owner()));
+ switch (sym.info()) {
+ case MethodType(Symbol[] vparams, scalac.symtab.Type result):
+ if (sym.name == Names.CONSTRUCTOR) {
+ TypeBuilder type = (TypeBuilder) getTypeFromType(result);
+ method = createMethod(type, sym.name, sym.info(), sym.flags);
+ } else {
+ int flags = ( owner.isJava() && owner.isModuleClass() ) ?
+ sym.flags | Modifiers.STATIC :
+ sym.flags;
+
+ TypeBuilder type = (TypeBuilder)getType(owner);
+ method = createMethod(type, sym.name, sym.info(), flags);
}
break;
default:
@@ -591,6 +670,7 @@ public final class TypeCreator
return method;
}
+
/** Returns teh FieldInfo object corresponing to the symbol
*/
public FieldInfo getField(Symbol sym) {
@@ -606,6 +686,9 @@ public final class TypeCreator
return field;
}
+
+ /**
+ */
public FieldInfo createField(Symbol sym) {
FieldBuilder field;
//log("createField: resolving symbol: " + dumpSym(sym));
@@ -622,6 +705,9 @@ public final class TypeCreator
return field;
}
+
+ /**
+ */
FieldInfo getModuleField(Type type) {
Symbol sym = (Symbol) types2symbols.get(type);
assert sym != null;
@@ -638,6 +724,9 @@ public final class TypeCreator
return null;
}
+
+ /**
+ */
FieldInfo getModuleField(Symbol sym) {
FieldInfo moduleField = null;
if (sym.isModule() || sym.isModuleClass()) {
@@ -669,8 +758,8 @@ public final class TypeCreator
return moduleField;
}
- /**
- * Translates Scala modifiers into TypeAttributes
+
+ /** Translates Scala modifiers into TypeAttributes
*/
public static long translateTypeAttributes(int mods, boolean nested) {
long attr = TypeAttributes.AutoLayout | TypeAttributes.AnsiClass;
@@ -702,8 +791,8 @@ public final class TypeCreator
return attr;
}
- /**
- * Translates Scala modifiers into FieldAttributes
+
+ /** Translates Scala modifiers into FieldAttributes
*/
public static long translateFieldAttributes(int mods) {
long attr = 0L;
@@ -723,8 +812,8 @@ public final class TypeCreator
return attr;
}
- /**
- * Translates Scala modifiers into MethodAttributes
+
+ /** Translates Scala modifiers into MethodAttributes
*/
public static long translateMethodAttributes(int mods, boolean constructor)
{
@@ -778,13 +867,14 @@ public final class TypeCreator
}
void log(String message) {
- //System.out.println(message);
+ System.out.println(message);
//log(1, message);
- global.reporter.printMessage(message);
+ //global.reporter.printMessage(message);
}
void logErr(String message) {
- global.reporter.printMessage(unit.position(pos), message);
+ System.err.println(message);
+ //global.reporter.printMessage(unit.position(pos), message);
}
} // class TypeCreator