Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

165
LINES

< > BotCompany Repo | #1002825 // structure function (v5, with new backrefs, old)

JavaX fragment (include)

// "seen" is now default
static String structure(Object o) {
  return structure(o, 0, new IdentityHashMap);
}

static String structure_seen(Object o) {
  return structure(o, 0, new IdentityHashMap);
}

// leave to false, unless unstructure() breaks
static boolean structure_allowShortening = false;
  
static String structure(Object o, int stringSizeLimit, IdentityHashMap<O, Integer> seen) {
  if (o == null) return "null";
  
  // these are never back-referenced (for readability)
  
  if (o instanceof String)
    return quote(stringSizeLimit != 0 ? shorten((String) o, stringSizeLimit) : (String) o);
    
  if (o instanceof BigInteger)
    return "bigint(" + o + ")";
  
  if (o instanceof Double)
    return "d(" + quote(str(o)) + ")";
    
  if (o instanceof Long)
    return o + "L";
  
  if (o instanceof Integer)
    return str(o);
  
  if (seen != null) {
    Integer ref = seen.get(o);
    if (ref != null)
      return "r" + ref;
      
    seen.put(o, seen.size()+1);
  }

  String name = o.getClass().getName();

  StringBuilder buf = new StringBuilder();
  
  if (o instanceof HashSet)
    return "hashset" + structure(new ArrayList((Set) o), stringSizeLimit, seen);

  if (o instanceof TreeSet)
    return "treeset" + structure(new ArrayList((Set) o), stringSizeLimit, seen);
  
  if (o instanceof Collection) {
    for (Object x : (Collection) o) {
      if (buf.length() != 0) buf.append(", ");
      buf.append(structure(x, stringSizeLimit, seen));
    }
    return "[" + buf + "]";
  }
  
  if (o instanceof Map) {
    for (Object e : ((Map) o).entrySet()) {
      if (buf.length() != 0) buf.append(", ");
      buf.append(structure(((Map.Entry) e).getKey(), stringSizeLimit, seen));
      buf.append("=");
      buf.append(structure(((Map.Entry) e).getValue(), stringSizeLimit, seen));
    }
    return (o instanceof HashMap ? "hashmap" : "") + "{" + buf + "}";
  }
  
  if (o.getClass().isArray()) {
    int n = Array.getLength(o);
    for (int i = 0; i < n; i++) {
      if (buf.length() != 0) buf.append(", ");
      buf.append(structure(Array.get(o, i), stringSizeLimit, seen));
    }
    return "array{" + buf + "}";
  }

  if (o instanceof Class)
    return "class(" + quote(((Class) o).getName()) + ")";
    
  if (o instanceof Throwable)
    return "exception(" + quote(((Throwable) o).getMessage()) + ")";
    
  // Need more cases? This should cover all library classes...
  if (name.startsWith("java.") || name.startsWith("javax."))
    return String.valueOf(o);
    
  String shortName = o.getClass().getName().replaceAll("^main\\$", "");
  
  if (shortName.equals("Lisp")) {
    buf.append("l(" + structure(getOpt(o, "head"), stringSizeLimit, seen));
    L args = cast getOpt(o, "args");
    if (nempty(args))
      for (int i = 0; i < l(args); i++) {
        buf.append(", ");
        O arg = args.get(i);
        
        // sweet shortening
        if (arg != null && eq(arg.getClass().getName(), "main$Lisp") && isTrue(call(arg, "isEmpty")))
          arg = get(arg, "head");
          
        buf.append(structure(arg, stringSizeLimit, seen));
      }
    buf.append(")");
    ret str(buf);
  }
    
  int numFields = 0;
  String fieldName = "";
  if (shortName.equals("DynamicObject")) {
    shortName = (String) get(o, "className");
    Map<String, Object> fieldValues = (Map) get(o, "fieldValues");
    
    for (String _fieldName : fieldValues.keySet()) {
      fieldName = _fieldName;
      Object value = fieldValues.get(fieldName);
      if (value != null) {
        if (buf.length() != 0) buf.append(", ");
        buf.append(fieldName + "=" + structure(value, stringSizeLimit, seen));
      }
      ++numFields;
   }
  } else {
    // regular class
    
    Class c = o.getClass();
    while (c != Object.class) {
      Field[] fields = c.getDeclaredFields();
      for (Field field : fields) {
        if ((field.getModifiers() & Modifier.STATIC) != 0)
          continue;
        fieldName = field.getName();
        
        // skip outer object reference
        if (fieldName.indexOf("$") >= 0) continue;
  
        Object value;
        try {
          field.setAccessible(true);
          value = field.get(o);
        } catch (Exception e) {
          value = "?";
        }
        
        // put special cases here...
    
        if (value != null) {
          if (buf.length() != 0) buf.append(", ");
          buf.append(fieldName + "=" + structure(value, stringSizeLimit, seen));
        }
        ++numFields;
      }
      c = c.getSuperclass();
    }
  }
  
  String b = buf.toString();
  
  if (numFields == 1 && structure_allowShortening)
    b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one
  String s = shortName;
  if (buf.length() != 0)
    s += "(" + b + ")";
  return s;
}

Author comment

Began life as a copy of #1001386

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002825
Snippet name: structure function (v5, with new backrefs, old)
Eternal ID of this version: #1002825/1
Text MD5: 9b3f2ddc8c396f0f40c18558f1b24a0f
Author: stefan
Category:
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-04-26 16:46:25
Source code size: 4939 bytes / 165 lines
Pitched / IR pitched: No / No
Views / Downloads: 590 / 1342
Referenced in: [show references]