package com.redhat.ceylon.compiler.test;

import java.lang.reflect.Field;

public final class dump extends ceylon.language.Object {
    public static void run(ceylon.language.Object obj) {
        Class klass = obj.getClass();
        System.out.println(klass.getName() + " {");
        for (Field field: klass.getDeclaredFields()) {
            String name = field.getName();
            if (name.equals("$assertionsDisabled"))
                continue;

            Object value;
            try {
                if (!field.isAccessible())
                    field.setAccessible(true);
                value = field.get(obj);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }

            String type = field.getType().getName();
            if (type.equals("char")) {
                value = formatChar((Character) value);
            }
            else if (type.equals("java.lang.String")) {
                value = formatString((String) value);
            }

            System.out.println("  "
                               + type
                               + " "
                               + name
                               + " = "
                               + value);
        }
        System.out.println("}");
    }

    private static String formatChar(char value) {
        return "'" + escape(value, '\'') + "'";
    }

    private static String formatString(String value) {
        StringBuilder builder = new StringBuilder();
        builder.append('"');
        for (int i = 0; i < value.length(); i++) {
            builder.append(escape(value.charAt(i), '"'));
        }
        builder.append('"');
        return builder.toString();
    }

    private static String escape(char value, char quote) {
        if (value == quote)
            return "\\" + value;

        switch (value) {
        case '\b':
            return "\\b";
        case '\t':
            return "\\t";
        case '\n':
            return "\\n";
        case '\f':
            return "\\f";
        case '\r':
            return "\\r";
        case '\\':
            return "\\\\";
        default:
            return Character.toString(value);
        }
    }
}

@@ -194,88 +194,464 @@
     
-Class klass = obj.getClass();%0A        System.out.println(klass.getName() + %22 %7B%22)
+StringBuilder builder = new StringBuilder();%0A        formatObject(builder, obj, %22%22);%0A        System.out.println(builder.toString());%0A    %7D%0A%0A    private static void formatObject(StringBuilder builder,%0A                                     Object obj,%0A                                     String indent) %7B%0A        Class klass = obj.getClass();%0A        builder.append(klass.getName());%0A        builder.append(%22 %7B%5Cn%22);%0A%0A        String moreIndent = indent + %22  %22
 ;%0A  
@@ -1121,22 +1121,21 @@
         
-String
+Class
  type = 
@@ -1149,27 +1149,245 @@
 etType()
-.getName();
+;%0A            String typeName = type.getName();%0A%0A            builder.append(moreIndent);%0A            builder.append(typeName);%0A            builder.append(' ');%0A            builder.append(name);%0A            builder.append(%22 = %22);%0A
 %0A       
@@ -1391,32 +1391,36 @@
         if (type
+Name
 .equals(%22char%22))
@@ -1433,32 +1433,24 @@
             
- value =
  formatChar(
@@ -1449,16 +1449,25 @@
 matChar(
+builder, 
 (Charact
@@ -1517,16 +1517,20 @@
 if (type
+Name
 .equals(
@@ -1567,24 +1567,16 @@
         
- value =
  formatS
@@ -1581,16 +1581,25 @@
 tString(
+builder, 
 (String)
@@ -1613,33 +1613,32 @@
 ;%0A            %7D%0A
-%0A
             Syst
@@ -1637,91 +1637,98 @@
     
-System.out.println(%22  %22%0A                               + type%0A                     
+else if (!type.isPrimitive()) %7B%0A                formatObject(builder, value, moreIndent);%0A
     
@@ -1737,13 +1737,11 @@
     
-+ %22 %22
+  %7D
 %0A   
@@ -1741,32 +1741,39 @@
   %7D%0A            
+else %7B%0A
                 
@@ -1776,17 +1776,30 @@
     
-   + name
+builder.append(value);
 %0A   
@@ -1799,32 +1799,35 @@
 e);%0A            
+%7D%0A%0A
                 
@@ -1826,100 +1826,94 @@
     
-       + %22 = %22%0A                               + value);%0A        %7D%0A        System.out.println
+builder.append('%5Cn');%0A        %7D%0A        builder.append(indent);%0A        builder.append
 (%22%7D%22
@@ -1937,30 +1937,28 @@
 vate static 
-String
+void
  formatChar(
@@ -1961,68 +1961,148 @@
 har(
-char value) %7B%0A        return %22'%22 + escape(value, '%5C'') + %22'%22
+StringBuilder builder, char value) %7B%0A        builder.append('%5C'');%0A        builder.append(escape(value, '%5C''));%0A        builder.append('%5C'')
 ;%0A  
@@ -2125,22 +2125,20 @@
  static 
-String
+void
  formatS
@@ -2147,32 +2147,8 @@
 ing(
-String value) %7B%0A        
 Stri
@@ -2164,39 +2164,33 @@
  builder
- = new
+,
  String
-Builder();
+ value) %7B
 %0A       
@@ -2363,43 +2363,8 @@
 ');%0A
-        return builder.toString();%0A
     

Make dump recursive