diff options
author | paltherr <paltherr@epfl.ch> | 2004-06-17 08:37:39 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2004-06-17 08:37:39 +0000 |
commit | fa64b1f6b2d998caf925147427ac7fc3ab35f2f2 (patch) | |
tree | 52ef2ad2f2a7b2f12fab2290a018fd46c91590e6 | |
parent | 2090a468ef5683ac4dc73ec81fee385ee3b8f304 (diff) | |
download | scala-fa64b1f6b2d998caf925147427ac7fc3ab35f2f2.tar.gz scala-fa64b1f6b2d998caf925147427ac7fc3ab35f2f2.tar.bz2 scala-fa64b1f6b2d998caf925147427ac7fc3ab35f2f2.zip |
- Added debugging classes in scala.tools.util.d...
- Added debugging classes in scala.tools.util.debug Added class
- scala.tools.util.StringBufferWriter
-rw-r--r-- | config/list/util.lst | 11 | ||||
-rw-r--r-- | sources/scala/tools/util/StringBufferWriter.java | 69 | ||||
-rw-r--r-- | sources/scala/tools/util/debug/AbortError.java | 43 | ||||
-rw-r--r-- | sources/scala/tools/util/debug/ArrayDebugger.java | 94 | ||||
-rw-r--r-- | sources/scala/tools/util/debug/Debug.java | 244 | ||||
-rw-r--r-- | sources/scala/tools/util/debug/Debugger.java | 34 | ||||
-rw-r--r-- | sources/scala/tools/util/debug/ObjectDebugger.java | 54 | ||||
-rw-r--r-- | sources/scala/tools/util/debug/ThrowableDebugger.java | 48 | ||||
-rw-r--r-- | sources/scala/tools/util/debug/ToStringDebugger.java | 44 |
9 files changed, 640 insertions, 1 deletions
diff --git a/config/list/util.lst b/config/list/util.lst index d43699437e..7ee9025357 100644 --- a/config/list/util.lst +++ b/config/list/util.lst @@ -13,8 +13,17 @@ PlainFile.java Position.java SourceFile.java SourceReader.java -VirtualFile.java +StringBufferWriter.java VirtualDirectory.java +VirtualFile.java ZipArchive.java +debug/AbortError.java +debug/ArrayDebugger.java +debug/Debug.java +debug/Debugger.java +debug/ObjectDebugger.java +debug/ThrowableDebugger.java +debug/ToStringDebugger.java + ############################################################################## diff --git a/sources/scala/tools/util/StringBufferWriter.java b/sources/scala/tools/util/StringBufferWriter.java new file mode 100644 index 0000000000..3e239b08cb --- /dev/null +++ b/sources/scala/tools/util/StringBufferWriter.java @@ -0,0 +1,69 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +import java.io.Writer; +import java.io.PrintWriter; + +/** This class implements a writer that writes to a string buffer. */ +public class StringBufferWriter extends Writer { + + //######################################################################## + // Private Fields + + private final StringBuffer buffer; + + //######################################################################## + // Public Constructors + + /** Initializes this instance with the specified string buffer. */ + public StringBufferWriter(StringBuffer buffer) { + this.buffer = buffer; + } + + //######################################################################## + // Public Methods + + /** Returns the underlying string buffer. */ + public StringBuffer getStringBuffer() { + return buffer; + } + + public void close() { + } + + public void flush() { + } + + public void write(int c) { + buffer.append((char)c); + } + + public void write(char[] cs) { + buffer.append(cs); + } + + public void write(char[] cs, int start, int count) { + buffer.append(cs, start, count); + } + + public void write(String string) { + buffer.append(string); + } + + public void write(String string, int start, int count) { + buffer.append(string.substring(start, start + count)); + } + + public String toString() { + return buffer.toString(); + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/debug/AbortError.java b/sources/scala/tools/util/debug/AbortError.java new file mode 100644 index 0000000000..25bdc3ed1d --- /dev/null +++ b/sources/scala/tools/util/debug/AbortError.java @@ -0,0 +1,43 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util.debug; + +/** + * This class implements an error that can be used to abort an + * application after an internal error. + */ +public class AbortError extends Error { + + //######################################################################## + // Protected Constructors + + /** Initializes this instance. */ + protected AbortError() { + super(); + } + + /** Initializes this instance with the specified message. */ + protected AbortError(String message) { + super(message); + } + + /** Initializes this instance with the specified cause. */ + protected AbortError(Throwable cause) { + this(cause); + } + + /** + * Initializes this instance with the specified message and cause. + */ + protected AbortError(String message, Throwable cause) { + super(message, cause); + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/debug/ArrayDebugger.java b/sources/scala/tools/util/debug/ArrayDebugger.java new file mode 100644 index 0000000000..6bc6621ab4 --- /dev/null +++ b/sources/scala/tools/util/debug/ArrayDebugger.java @@ -0,0 +1,94 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util.debug; + +/** This class implements a debugger that appends arrays. */ +public class ArrayDebugger implements Debugger { + + //######################################################################## + // Public Constants + + /** The unique instance of this class. */ + public static final ArrayDebugger object = new ArrayDebugger(); + + //######################################################################## + // Protected Constructors + + /** Initializes this instance. */ + protected ArrayDebugger() {} + + //######################################################################## + // Public Methods + + public boolean canAppend(Object object) { + return object.getClass().isArray(); + } + + public void append(StringBuffer buffer, Object object) { + buffer.append('['); + if (object instanceof Object[]) { + Object[] array = (Object[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + Debug.append(buffer, array[i]); + } + } else if (object instanceof boolean[]) { + boolean[] array = (boolean[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } else if (object instanceof byte[]) { + byte[] array = (byte[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } else if (object instanceof short[]) { + short[] array = (short[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } else if (object instanceof char[]) { + char[] array = (char[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } else if (object instanceof int[]) { + int[] array = (int[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } else if (object instanceof long[]) { + long[] array = (long[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } else if (object instanceof float[]) { + float[] array = (float[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } else if (object instanceof double[]) { + double[] array = (double[])object; + for (int i = 0; i < array.length; i++) { + if (i > 0) buffer.append(','); + buffer.append(array[i]); + } + } + buffer.append(']'); + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/debug/Debug.java b/sources/scala/tools/util/debug/Debug.java new file mode 100644 index 0000000000..38ee3c7b9a --- /dev/null +++ b/sources/scala/tools/util/debug/Debug.java @@ -0,0 +1,244 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util.debug; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; + +/** + * This class is intended to help debugging applications. It provides + * functions to abort the application and to turn objects into + * strings. + * + * In order to turn objects into strings, the class maintains a list + * of debuggers. An application using this class should configure it + * by adding debuggers for its data types (see method "addDebugger"). + * + * Each time an object has to be transformed into a string, the list + * of debuggers is searched from the last added one to the first one + * for a debugger that is able to make that transformation. The first + * that is found, is then used to make the transformation. + */ +public class Debug { + + //######################################################################## + // Private Variables + + /** The list of all available debuggers */ + private static final ArrayList/*<Debugger>*/ debuggers = new ArrayList(); + + static { + addDebugger(ObjectDebugger.object); + addDebugger(ArrayDebugger.object); + addDebugger(ThrowableDebugger.object); + addDebugger(new ToStringDebugger(String.class)); + } + + //######################################################################## + // Public Methods - Configuring + + /** Adds the specified debugger to the list of debuggers. */ + public static void addDebugger(Debugger debugger) { + debuggers.add(debugger); + } + + //######################################################################## + // Public Methods - Aborting + + /** Aborts the application by throwing an AbortError. */ + public static Error abort() { + throw new AbortError(); + } + public static Error abort(Throwable cause) { + throw new AbortError(cause); + } + public static Error abort(Object object) { + return abort(show(object)); + } + public static Error abort(Object object, Throwable cause) { + return abort(show(object), cause); + } + public static Error abort(String message) { + throw new AbortError(message); + } + public static Error abort(String message, Throwable cause) { + throw new AbortError(message, cause); + } + public static Error abort(String message, Object object) { + return abort(message + ": " + show(object)); + } + public static Error abort(String message, Object object, Throwable cause) { + return abort(message + ": " + show(object), cause); + } + + /** Aborts the application by throwing an AbortError. */ + public static Error abortIllegalCase(int value) { + return abort("illegal case: " + value); + } + public static Error abortIllegalCase(Object object) { + return abort("illegal case", object); + } + + //######################################################################## + // Public Methods - Showing + + /** + * Makes a string out of the object(s) using for each the first + * matching debugger and separating them with dash(es). + */ + public static String show(Object a) { + return showAll(new Object[] {a}); + } + public static String show(Object a, Object b) { + return showAll(new Object[] {a, b}); + } + public static String show(Object a, Object b, Object c) { + return showAll(new Object[] {a, b, c}); + } + public static String show(Object a, Object b, Object c, Object d) { + return showAll(new Object[] {a, b, c, d}); + } + public static String show(Object a, Object b, Object c, Object d, Object e) + { + return showAll(new Object[] {a, b, c, d, e}); + } + public static String show(Object a, Object b, Object c, Object d, Object e, + Object f) + { + return showAll(new Object[] {a, b, c, d, e, f}); + } + public static String show(Object a, Object b, Object c, Object d, Object e, + Object f, Object g) + { + return showAll(new Object[] {a, b, c, d, e, f, g}); + } + public static String show(Object a, Object b, Object c, Object d, Object e, + Object f, Object g, Object h) + { + return showAll(new Object[] {a, b, c, d, e, f, g, h}); + } + public static String show(Object a, Object b, Object c, Object d, Object e, + Object f, Object g, Object h, Object i) + { + return showAll(new Object[] {a, b, c, d, e, f, g, h, i}); + } + public static String show(Object a, Object b, Object c, Object d, Object e, + Object f, Object g, Object h, Object i, Object j) + { + return showAll(new Object[] {a, b, c, d, e, f, g, h, i, j}); + } + public static String show(Object a, Object b, Object c, Object d, Object e, + Object f, Object g, Object h, Object i, Object j, Object k) + { + return showAll(new Object[] {a, b, c, d, e, f, g, h, i, j, k}); + } + public static String show(Object a, Object b, Object c, Object d, Object e, + Object f, Object g, Object h, Object i, Object j, Object k, Object l) + { + return showAll(new Object[] {a, b, c, d, e, f, g, h, i, j, k, l}); + } + + /** + * Makes a string out of all objects using for each the first + * matching debugger and separating them with dashes. + */ + public static String showAll(Object[] objects) { + return showAll(objects, " - "); + } + + /** + * Makes a string out of all objects using for each the first + * matching debugger and separating them with the specified + * separator if it is non-null and by nothing otherwise. + */ + public static String showAll(Object[] objects, String separator) { + StringBuffer buffer = new StringBuffer(); + appendAll(buffer, objects, separator); + return buffer.toString(); + } + + //######################################################################## + // Public Methods - Appending + + /** + * Appends the object to the buffer using the first matching + * debugger. + */ + public static void append(StringBuffer buffer, Object object) { + if (object != null) { + for (int i = debuggers.size() - 1; i >= 0; i--) { + Debugger debugger = (Debugger)debuggers.get(i); + if (!debugger.canAppend(object)) continue; + debugger.append(buffer, object); + return; + } + } + buffer.append(object); + } + + /** + * Appends all the objects to the buffer using for each the first + * matching debugger. The object are separated by the specified + * separator if it is non-null and by nothing otherwise. + */ + public static void appendAll(StringBuffer buffer, Object[] objects, + String separator) + { + for (int i = 0; i < objects.length; i++) { + if (i > 0 && separator != null) buffer.append(separator); + append(buffer, objects[i]); + } + } + + //######################################################################## + // Public Methods - Miscellaneous + + /** + * Returns the class name of the object. Does some pretty printing + * for parameterless pico case classes. + */ + public static String getClassNameOf(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; + } + + /** Returns true iff the object overrides "Object.toString()". */ + public static boolean overridesToString(Object object) { + try { + Class clasz = object.getClass(); + Method toString = clasz.getMethod("toString", new Class[0]); + return toString.getDeclaringClass() != Object.class; + } catch (NoSuchMethodException exception) { + return false; + } catch (SecurityException exception) { + return false; + } + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/debug/Debugger.java b/sources/scala/tools/util/debug/Debugger.java new file mode 100644 index 0000000000..0a40f74768 --- /dev/null +++ b/sources/scala/tools/util/debug/Debugger.java @@ -0,0 +1,34 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util.debug; + +/** + * This interface defines methods used by the class Debug to turn + * objects into strings. + */ +public interface Debugger { + + //######################################################################## + // Public Methods + + /** + * Returns "true" if the specified object may be passed as an + * argument to the method "append". + */ + public boolean canAppend(Object object); + + /** + * Appends the object to the string buffer. This method must be + * invoked only with objects for which the method "canAppend" + * returns "true". + */ + public void append(StringBuffer buffer, Object object); + + //######################################################################## +} diff --git a/sources/scala/tools/util/debug/ObjectDebugger.java b/sources/scala/tools/util/debug/ObjectDebugger.java new file mode 100644 index 0000000000..7edcdbd0f0 --- /dev/null +++ b/sources/scala/tools/util/debug/ObjectDebugger.java @@ -0,0 +1,54 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util.debug; + +/** + * This class implements a debugger that appends any object. It + * appends the class name of the object and either the string returned + * by its method "toString" if it overridden or its identity hash code + * otherwise. + */ +public class ObjectDebugger implements Debugger { + + //######################################################################## + // Public Constants + + /** The unique instance of this class. */ + public static final ObjectDebugger object = new ObjectDebugger(); + + //######################################################################## + // Protected Constructors + + /** Initializes this instance. */ + protected ObjectDebugger() {} + + //######################################################################## + // Public Methods + + public boolean canAppend(Object object) { + return true; + } + + public void append(StringBuffer buffer, Object object) { + buffer.append(Debug.getClassNameOf(object)); + Class owner = null; + if (Debug.overridesToString(object)) { + buffer.append('('); + buffer.append(object); + buffer.append(')'); + } else { + String code = Integer.toHexString(System.identityHashCode(object)); + buffer.append('@'); + for (int i = code.length(); i < 8; i++) buffer.append('0'); + buffer.append(code); + } + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/debug/ThrowableDebugger.java b/sources/scala/tools/util/debug/ThrowableDebugger.java new file mode 100644 index 0000000000..8bdf93cbcb --- /dev/null +++ b/sources/scala/tools/util/debug/ThrowableDebugger.java @@ -0,0 +1,48 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util.debug; + +import java.io.Writer; +import java.io.PrintWriter; + +import scala.tools.util.StringBufferWriter; + +/** + * This class implements a debugger that appends instances of + * Throwable. + */ +public class ThrowableDebugger implements Debugger { + + //######################################################################## + // Public Constants + + /** The unique instance of this class. */ + public static final ThrowableDebugger object = new ThrowableDebugger(); + + //######################################################################## + // Protected Constructors + + /** Initializes this instance. */ + protected ThrowableDebugger() {} + + //######################################################################## + // Public Methods + + public boolean canAppend(Object object) { + return object instanceof Throwable; + } + + public void append(StringBuffer buffer, Object object) { + PrintWriter writer = new PrintWriter(new StringBufferWriter(buffer)); + ((Throwable)object).printStackTrace(writer); + writer.close(); + } + + //######################################################################## +} diff --git a/sources/scala/tools/util/debug/ToStringDebugger.java b/sources/scala/tools/util/debug/ToStringDebugger.java new file mode 100644 index 0000000000..85e0e18776 --- /dev/null +++ b/sources/scala/tools/util/debug/ToStringDebugger.java @@ -0,0 +1,44 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util.debug; + +/** + * This class implements a debugger that appends objects that are + * instances of a specified class (or of one of its subclass) by + * simply appending the string returned by their method "toString". + */ +public class ToStringDebugger implements Debugger { + + //######################################################################## + // Private Fields + + /** The class whose instances can be appended */ + private final Class clasz; + + //######################################################################## + // Public Constructors + + /** Initializes this instance. */ + public ToStringDebugger(Class clasz) { + this.clasz = clasz; + } + + //######################################################################## + // Public Methods + + public boolean canAppend(Object object) { + return clasz.isInstance(object); + } + + public void append(StringBuffer buffer, Object object) { + buffer.append(object.toString()); + } + + //######################################################################## +} |