summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2004-03-26 08:59:58 +0000
committermihaylov <mihaylov@epfl.ch>2004-03-26 08:59:58 +0000
commitd88a6cb1e445486e00a8cf167a410b14cf55cbf0 (patch)
tree5f8e9fd5234fcad3e91cd07970e91ee76c091ea4
parentb4745afc1967907eef0371212ad79c0b553f0c05 (diff)
downloadscala-d88a6cb1e445486e00a8cf167a410b14cf55cbf0.tar.gz
scala-d88a6cb1e445486e00a8cf167a410b14cf55cbf0.tar.bz2
scala-d88a6cb1e445486e00a8cf167a410b14cf55cbf0.zip
- Moved a MSIL specific feature from Erasure to...
- Moved a MSIL specific feature from Erasure to the TypeCreator class of the MSIL backend
-rw-r--r--sources/scalac/backend/msil/TypeCreator.java72
-rw-r--r--sources/scalac/transformer/Erasure.java7
2 files changed, 59 insertions, 20 deletions
diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java
index 0ffd145dbd..2e701e7544 100644
--- a/sources/scalac/backend/msil/TypeCreator.java
+++ b/sources/scalac/backend/msil/TypeCreator.java
@@ -28,10 +28,11 @@ import ch.epfl.lamp.compiler.msil.*;
import ch.epfl.lamp.compiler.msil.emit.*;
import java.util.Map;
+import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
-import java.util.LinkedHashSet;
+import java.util.HashSet;
/**
* Creates System.Reflection objects corresponding to
@@ -517,7 +518,7 @@ final class TypeCreator {
public Type createType(Symbol clazz) {
try { return createType0(clazz); }
- catch (RuntimeException e) {
+ catch (Error e) {
System.err.println("while creating type for " + Debug.show(clazz));
System.err.println("" + clazz.members());
throw e;
@@ -593,31 +594,66 @@ final class TypeCreator {
typeBuilders.add(type);
map(clazz, type);
- // 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 = clazz.members().iterator();
+ for (Scope.SymbolIterator syms = clazz.members().iterator(true);
syms.hasNext(); )
{
- Symbol[] members = syms.next().alternativeSymbols();
- for (int i = 0; i < members.length; i++) {
- if (members[i].isMethod() /*&& !members[i].isModule()*/) {
- createMethod(members[i]);
- }
- else if (!members[i].isClass()
- && !members[i].isModule()
- && !members[i].isType())
- {
- createField(members[i]);
- }
- }
+ Symbol member = syms.next();
+ if (member.isMethod())
+ createMethod(member);
+ else if (!member.isClass() && !member.isModule()
+ && !member.isType())
+ createField(member);
}
- //System.out.println("created type: " + Debug.show(clazz));
+ // adapted from Erasure; creates abstract method declarations
+ // for the interface methods for which the class doesn't provide
+ // implementation (requirement of the CLR)
+ if (clazz.isClass() && !clazz.isInterface()) {
+ Set ifaces = new HashSet(getInterfacesOf(clazz));
+ Symbol svper = clazz.parents()[0].symbol();
+ ifaces.removeAll(getInterfacesOf(svper));
+ for (Iterator i = ifaces.iterator(); i.hasNext(); ) {
+ Symbol iface = (Symbol)i.next();
+ for (Scope.SymbolIterator members = iface.members().iterator(true);
+ members.hasNext(); )
+ {
+ Symbol method = members.next();
+ if (!method.isTerm() || !method.isDeferred()) continue;
+ Symbol overriding =
+ method.overridingSymbol(clazz.info(), true);
+ if (overriding != method) continue;
+ Symbol overridden = method
+ .overriddenSymbol(clazz.parents()[0], clazz, true);
+ if (overridden.isNone()) {
+ Symbol newMethod = method.cloneSymbol(clazz);
+ newMethod.flags = (newMethod.flags & ~Modifiers.JAVA)
+ | Modifiers.SYNTHETIC | Modifiers.DEFERRED;
+ createMethod(newMethod);
+ }
+ }
+ }
+ }
return type;
} // createType()
+ private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap();
+
+ private Set getInterfacesOf(Symbol clasz) {
+ assert clasz.isClass(): Debug.show(clasz);
+ Set set = (Set)interfaces.get(clasz);
+ if (set == null) {
+ set = new HashSet();
+ interfaces.put(clasz, set);
+ scalac.symtab.Type parents[] = clasz.parents();
+ for (int i = 0; i < parents.length; i++)
+ set.addAll(getInterfacesOf(parents[i].symbol()));
+ if (clasz.isInterface()) set.add(clasz);
+ }
+ return set;
+ }
+
/**
* Returns the MethodBase object corresponding to the symbol.
*/
diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java
index 84a12b597d..f142f6f623 100644
--- a/sources/scalac/transformer/Erasure.java
+++ b/sources/scalac/transformer/Erasure.java
@@ -671,6 +671,7 @@ public class Erasure extends GenTransformer implements Modifiers {
* CLR's requirement that classes should provide declaration
* for all methods of the interfaces they implement
*/
+ /*
public void addEmptyBridge(Symbol owner, Symbol method) {
Type bridgeType = method.nextType();
Symbol bridgeSym = method.cloneSymbol(owner);
@@ -689,6 +690,7 @@ public class Erasure extends GenTransformer implements Modifiers {
bridges.append(bridge);
}
}
+ */
private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap();
@@ -748,8 +750,9 @@ public class Erasure extends GenTransformer implements Modifiers {
Symbol overridden = method.overriddenSymbol(owner.thisType().parents()[0], owner);
if (!overridden.isNone() && !isSameAs(overridden.nextType(), method.nextType()))
addBridge(owner, method, overridden);
- if (forMSIL && (overridden.isNone() || overridden.owner() != owner))
- addEmptyBridge(owner, method);
+ // moved this into the TypeCreator class of the MSIL backend
+ //if (forMSIL && (overridden.isNone() || overridden.owner() != owner))
+ // addEmptyBridge(owner, method);
} else if (!overriding.isNone() && !isSameAs(overriding.nextType(), method.nextType()))
addBridge(owner, overriding, method);
}