diff options
author | Martin Odersky <odersky@gmail.com> | 2003-02-13 14:41:36 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-02-13 14:41:36 +0000 |
commit | 4177daab2f54bdb20c71f623296a8bb32616fd12 (patch) | |
tree | 23f08b43f3758e825d5965b336030603a65bbcf7 /sources/scalac/util/Debug.java | |
parent | 33d6e170c97ca7b2f991896a0729941a7240b6d6 (diff) | |
download | scala-4177daab2f54bdb20c71f623296a8bb32616fd12.tar.gz scala-4177daab2f54bdb20c71f623296a8bb32616fd12.tar.bz2 scala-4177daab2f54bdb20c71f623296a8bb32616fd12.zip |
Initial version.
Diffstat (limited to 'sources/scalac/util/Debug.java')
-rw-r--r-- | sources/scalac/util/Debug.java | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/sources/scalac/util/Debug.java b/sources/scalac/util/Debug.java new file mode 100644 index 0000000000..4597463aab --- /dev/null +++ b/sources/scalac/util/Debug.java @@ -0,0 +1,465 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +** ** +\* */ + +// $Id$ + +package scalac.util; + +import java.util.HashMap; + +import java.lang.reflect.Modifier; +import java.lang.reflect.Method; +import java.lang.reflect.Field; + +import scalac.Global; +import scalac.ApplicationError; +import scalac.symtab.Type; +import scalac.symtab.Symbol; +import scalac.symtab.Scope; + +/** + * Debugging class, used e.g. to obtain string representations of + * compiler data structures that are not "pretty-printed" and thus + * easier to relate to the source code. + * + * All methods are static to be easily useable in any context. + * + * @author Michel Schinz + * @version 1.0 + */ + +public abstract class Debug { + + //######################################################################## + // Debug interface - abort + + public static Error abort() { + return new ApplicationError(); + } + + public static Error abort(String message) { + return new ApplicationError(message); + } + + public static Error abort(Object object) { + return new ApplicationError(object); + } + + public static Error abort(Throwable cause) { + return new ApplicationError(cause); + } + + public static Error abort(String message, Object object) { + return new ApplicationError(message, object); + } + + public static Error abort(String message, Throwable cause) { + return new ApplicationError(message, cause); + } + + public static Error abort(Object object, Throwable cause) { + return new ApplicationError(object, cause); + } + + public static Error abort(String message, Object object, Throwable cause) { + return new ApplicationError(message, object, cause); + } + + //######################################################################## + // Debug interface - log + + public static boolean log(String message) { + return Global.instance.log(message); + } + + public static boolean log(String message, Object object) { + return log(message + ": " + show(object)); + } + + //######################################################################## + // Debug interface - handlers + + public static final HashMap/*<Class,DebugHandler>*/ handlers; + + static { + handlers = new HashMap(); + handlers.put(String.class, DebugToStringHandler.instance); + handlers.put(Type.class, DebugType.instance); + handlers.put(Symbol.class, DebugSymbol.instance); + handlers.put(Scope.class, DebugScope.instance); + } + + public static DebugHandler getHandler(Object that) { + if (that == null) return DebugDefaultHandler.instance; + return getHandler(that.getClass()); + } + + public static DebugHandler getHandler(Class clasz) { + if (clasz == null) return DebugDefaultHandler.instance; + Object handler = handlers.get(clasz); + if (handler != null) return (DebugHandler)handler; + return getHandler(clasz.getSuperclass()); + } + + //######################################################################## + // Debug interface - toString + + public static String toString(Object that) { + return show(that); + } + + //######################################################################## + // Debug interface - show + + public static String show(Object that) { + return show(that, getHandler(that)); + } + + public static String show(Object that, DebugHandler handler) { + StringBuffer buffer = new StringBuffer(); + handler.append0(buffer, that); + return buffer.toString(); + } + + //######################################################################## + // Debug interface - append + + public static void append(StringBuffer buffer, Object that) { + getHandler(that).append0(buffer, that); + } + + public static void appendDefault(StringBuffer buffer, Object that) { + if (that == null) { buffer.append("null"); return; } + if (!that.getClass().isArray()) { + appendObject(buffer, that); + } else { + appendArray(buffer, (Object[])that); + } + } + + public static void appendObject(StringBuffer buffer, Object that) { + if (that == null) { buffer.append("null"); return; } + buffer.append(getClassName(that)); + Class owner = null; + if (hasToString(that.getClass())) { + buffer.append('('); + buffer.append(that); + buffer.append(')'); + } else { + int code = System.identityHashCode(that); + buffer.append('@'); + buffer.append(Integer.toHexString(code)); + } + } + + public static void appendArray(StringBuffer buffer, Object[] that) { + if (that == null) { buffer.append("null"); return; } + buffer.append('['); + for (int i = 0; i < that.length; i++) { + if (i > 0) buffer.append(','); + append(buffer, that[i]); + } + buffer.append(']'); + } + + //######################################################################## + // Debug interface - utils + + public static final Class OBJECT_CLASS = Object.class; + + public static boolean hasToString(Class clasz) { + try { + Method toString = clasz.getMethod("toString", new Class[0]); + return toString.getDeclaringClass() != OBJECT_CLASS; + } catch (NoSuchMethodException excpetion) { + return false; + } catch (SecurityException excpetion) { + return false; + } + } + + public static String getClassName(Object object) { + if (object == null) return "null"; + Class clasz = object.getClass(); + String name = clasz.getName(); + if (!name.endsWith("$$Var")) return name; + Class superclass = clasz.getSuperclass(); + Field[] fields = superclass.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + try { + Field field = fields[i]; + if (field.getType() != clasz) continue; + if (!Modifier.isStatic(field.getModifiers())) continue; + Object value = field.get(null); + if (value != object) continue; + return name + "[" + field.getName() + "]"; + } catch (IllegalAccessException exception) { + // continue + } + } + return name; + } + + //######################################################################## +} + +public interface DebugHandler { + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that); + + //######################################################################## +} + +public abstract class DebugAbstractHandler implements DebugHandler { + + //######################################################################## + // DebugAbstractHandler interface + + public String show(Object that) { + return Debug.show(that, this); + } + + //######################################################################## +} + +public class DebugDefaultHandler extends DebugAbstractHandler { + + //######################################################################## + // DebugDefaultHandler interface + + public static DebugDefaultHandler instance = new DebugDefaultHandler(); + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that) { + Debug.appendDefault(buffer, that); + } + + //######################################################################## +} + +public class DebugToStringHandler extends DebugAbstractHandler { + + //######################################################################## + // DebugToStringHandler interface + + public static DebugToStringHandler instance = new DebugToStringHandler(); + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that) { + buffer.append(that); + } + + //######################################################################## +} + +public class DebugObject extends DebugAbstractHandler { + + //######################################################################## + // DebugObject interface + + public static DebugObject instance = new DebugObject(); + + public void append1(StringBuffer buffer, Object that) { + Debug.appendObject(buffer, that); + } + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that) { + append1(buffer, (Object)that); + } + + //######################################################################## +} + +public class DebugArray extends DebugAbstractHandler { + + //######################################################################## + // DebugArray interface + + public static DebugArray instance = new DebugArray(); + + public void append1(StringBuffer buffer, Object[] that) { + Debug.appendArray(buffer, that); + } + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that) { + append1(buffer, (Object[])that); + } + + //######################################################################## +} + +public class DebugType extends DebugAbstractHandler { + + //######################################################################## + // DebugType interface + + public static DebugType instance = new DebugType(); + + public void append1(StringBuffer buffer, Type that) { + switch (that) { + + case ErrorType: + buffer.append("ErrorType"); + return; + + case AnyType: + buffer.append("AnyType"); + return; + + case NoType: + buffer.append("NoType"); + return; + + case ThisType(Symbol symbol): + buffer.append("ThisType("); + Debug.append(buffer, symbol); + buffer.append(')'); + return; + + case TypeRef(Type prefix, Symbol symbol, Type[] args) : + buffer.append("TypeRef("); + Debug.append(buffer, prefix); + buffer.append(','); + Debug.append(buffer, symbol); + buffer.append(','); + Debug.append(buffer, args); + buffer.append(')'); + return; + + case SingleType(Type prefix, Symbol symbol): + buffer.append("SingleType("); + Debug.append(buffer, prefix); + buffer.append(','); + Debug.append(buffer, symbol); + buffer.append(')'); + return; + + case CompoundType(Type[] basetypes, Scope members): + buffer.append("CompoundType("); + Debug.append(buffer, basetypes); + buffer.append(','); + Debug.append(buffer, members); + buffer.append(')'); + return; + + case MethodType(Symbol[] vparams, Type result): + buffer.append("MethodType("); + Debug.append(buffer, vparams); + buffer.append(','); + Debug.append(buffer, result); + buffer.append(')'); + return; + + case PolyType(Symbol[] tparams, Type result): + buffer.append("PolyType("); + Debug.append(buffer, tparams); + buffer.append(','); + Debug.append(buffer, result); + buffer.append(')'); + return; + + case CovarType(Type tp): + buffer.append("CovarType("); + Debug.append(buffer, tp); + buffer.append(')'); + return; + + case OverloadedType(Symbol[] alts, Type[] alttypes): + buffer.append("OverloadedType("); + Debug.append(buffer, alts); + buffer.append(','); + Debug.append(buffer, alttypes); + buffer.append(')'); + return; + + default: + Debug.appendDefault(buffer, that); + return; + } + } + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that) { + append1(buffer, (Type)that); + } + + //######################################################################## +} + +public class DebugSymbol extends DebugAbstractHandler { + + //######################################################################## + // DebugSymbol interface + + public static DebugSymbol instance = new DebugSymbol(); + + public void append1(StringBuffer buffer, Symbol that) { + if (that != Symbol.NONE && that != Symbol.ERROR) { + buffer.append(that.kindString()).append(' '); + if (that.owner() != Global.instance.definitions.ROOT_CLASS) { + buffer.append(that.owner().fullName()); + buffer.append("::"); + } + } + buffer.append(that.name); + if (Global.instance.uniqid) { + buffer.append('#'); + buffer.append(Global.instance.uniqueID.id(that)); + } + } + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that) { + append1(buffer, (Symbol)that); + } + + //######################################################################## +} + +public class DebugScope extends DebugAbstractHandler { + + //######################################################################## + // DebugScope interface + + public static DebugScope instance = new DebugScope(); + + public void append1(StringBuffer buffer, Scope that) { + buffer.append('{'); + for (Scope.SymbolIterator i = that.iterator(); i.hasNext();) { + Debug.append(buffer, i.next()); + if (i.hasNext()) buffer.append(','); + } + buffer.append('}'); + } + + //######################################################################## + // DebugHandler interface + + public void append0(StringBuffer buffer, Object that) { + append1(buffer, (Scope)that); + } + + //######################################################################## +} + |