diff options
author | paltherr <paltherr@epfl.ch> | 2003-05-14 11:11:01 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2003-05-14 11:11:01 +0000 |
commit | 16b7be07c6af2ff1b205c13bfc7d32e1b6f40686 (patch) | |
tree | aa56e5ba4cf19b37ff792a09176e1db4eeb8a2c8 | |
parent | a575f59c3b640cc677c3a59751a70d633d43cf9d (diff) | |
download | scala-16b7be07c6af2ff1b205c13bfc7d32e1b6f40686.tar.gz scala-16b7be07c6af2ff1b205c13bfc7d32e1b6f40686.tar.bz2 scala-16b7be07c6af2ff1b205c13bfc7d32e1b6f40686.zip |
- Added SymbolSubstTypeMap.java
-rw-r--r-- | sources/scalac/symtab/SymbolSubstTypeMap.java | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/sources/scalac/symtab/SymbolSubstTypeMap.java b/sources/scalac/symtab/SymbolSubstTypeMap.java new file mode 100644 index 0000000000..0ecbacc1d9 --- /dev/null +++ b/sources/scalac/symtab/SymbolSubstTypeMap.java @@ -0,0 +1,147 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scalac.symtab; + +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; +import java.util.Set; + +import scalac.util.Debug; + +/** A type map that substitues symbols and types for symbols. */ +public class SymbolSubstTypeMap extends Type.Map { + + //######################################################################## + // Private Fields + + /** A table containing the symbol to symbol substitutions */ + private Map/*<Symbol, Symbol>*/ symbols; + + /** A table containing the symbol to type substitutions */ + private Map/*<Symbol, Type>*/ types; + + //######################################################################## + // Public Constructors + + public SymbolSubstTypeMap() { + this.symbols = new HashMap(); + this.types = new HashMap(); + } + + public SymbolSubstTypeMap(Map symbols, Map types) { + this(); + insertSymbol(symbols); + insertType(symbols); + } + + //######################################################################## + // Public Methods - Inserting and removing symbol to symbol substitutions + + public void insertSymbol(Symbol[] keys, Symbol[] values) { + assert keys.length == values.length : keys.length+" != "+values.length; + for (int i = 0; i < keys.length; i++) insertSymbol(keys[i], values[i]); + } + + public void insertSymbol(Symbol key, Symbol value) { + assert !types.containsKey(key) : Debug.show(key); + symbols.put(key, value); + } + + public void insertSymbol(Map map) { + assert checkLeftContainsNoKeyFromRight(types, map); + symbols.putAll(map); + } + + public void removeSymbol(Symbol[] keys) { + for (int i = 0; i < keys.length; i++) removeSymbol(keys[i]); + } + + public void removeSymbol(Symbol key) { + symbols.remove(key); + } + + public void removeSymbol(Set keys) { + symbols.keySet().removeAll(keys); + } + + //######################################################################## + // Public Methods - Inserting and removing symbol to type substitutions + + public void insertType(Symbol[] keys, Type[] values) { + assert keys.length == values.length : keys.length+" != "+values.length; + for (int i = 0; i < keys.length; i++) insertType(keys[i], values[i]); + } + + public void insertType(Symbol key, Type value) { + assert !symbols.containsKey(key) : Debug.show(key); + types.put(key, value); + } + + public void insertType(Map map) { + assert checkLeftContainsNoKeyFromRight(symbols, map); + types.putAll(map); + } + + public void removeType(Symbol[] keys) { + for (int i = 0; i < keys.length; i++) removeType(keys[i]); + } + + public void removeType(Symbol key) { + types.remove(key); + } + + public void removeType(Set keys) { + types.keySet().removeAll(keys); + } + + //######################################################################## + // Public Methods - Applying the substitutions + + public Type apply(Type type) { + switch (type) { + + case TypeRef(ThisType(_), Symbol symbol, Type[] args): { + Object value = types.get(symbol); + if (value != null) return (Type)value; + value = symbols.get(symbol); + if (value == null) return super.map(type); + Type prefix = ((Type.TypeRef)type).pre; + return Type.typeRef(apply(prefix), (Symbol)value, map(args)); + } + + case SingleType(ThisType(_), Symbol symbol): { + Object value = types.get(symbol); + if (value != null) return (Type)value; + value = symbols.get(symbol); + if (value == null) return super.map(type); + Type prefix = ((Type.TypeRef)type).pre; + return Type.singleType(apply(prefix), (Symbol)value); + } + + // TODO what should we do with PolyTypes? + + default: + return super.map(type); + } + } + + //######################################################################## + // Private Function + + private static boolean checkLeftContainsNoKeyFromRight(Map lf, Map rg) { + for (Iterator i = rg.keySet().iterator(); i.hasNext(); ) { + Object key = i.next(); + assert !lf.containsKey(key) : Debug.show(key); + } + return true; + } + + //######################################################################## +} |