-\r
- private DataTypePrinter2(StringBuilder sb) {\r
- this.sb = sb;\r
- }\r
-\r
- void newLine() {\r
- sb.append('\n');\r
- for(int i=0;i<indentation;++i)\r
- sb.append(" ");\r
- }\r
- \r
- boolean useRef = true;\r
- Visitor<Object> printVisitor = new Visitor<Object>() {\r
-\r
- @Override\r
- public Object visit(ArrayType b) {\r
- useRef = true;\r
- sb.append("Array(");\r
- b.componentType.accept(printVisitor);\r
- sb.append(")");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(BooleanType b) {\r
- useRef = true;\r
- sb.append("Boolean");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(DoubleType b) {\r
- useRef = true;\r
- sb.append("Double");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(FloatType b) {\r
- useRef = true;\r
- sb.append("Float");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(IntegerType b) {\r
- useRef = true;\r
- sb.append("Integer");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(ByteType b) {\r
- useRef = true;\r
- sb.append("Byte");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(LongType b) {\r
- useRef = true;\r
- sb.append("Long");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(OptionalType b) {\r
- useRef = true;\r
- sb.append("Optional(");\r
- b.componentType.accept(printVisitor);\r
- sb.append(")");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(RecordType b) {\r
- if(refs.containsKey(b) && useRef)\r
- sb.append(refs.get(b));\r
- else {\r
- useRef = true;\r
- sb.append("{");\r
- ++indentation;\r
- for(int i=0;i<b.getComponentCount();++i) {\r
- if(i > 0)\r
- sb.append(", ");\r
- Component c = b.getComponent(i);\r
- newLine();\r
- sb.append(c.name);\r
- sb.append(" : ");\r
- c.type.accept(printVisitor);\r
- }\r
- --indentation;\r
- newLine();\r
- sb.append("}");\r
- }\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(StringType b) {\r
- useRef = true;\r
- sb.append("String");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(UnionType b) {\r
- if(refs.containsKey(b) && useRef)\r
- sb.append(refs.get(b));\r
- else {\r
- useRef = true;\r
- ++indentation;\r
- for(int i=0;i<b.getComponentCount();++i) {\r
- newLine();\r
- sb.append("| ");\r
- Component c = b.getComponent(i);\r
- sb.append(c.name);\r
- sb.append(" ");\r
- c.type.accept(printVisitor);\r
- }\r
- --indentation;\r
- }\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(VariantType b) {\r
- useRef = true;\r
- sb.append("Variant");\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(MapType b) {\r
- useRef = true;\r
- sb.append("Map(");\r
- b.keyType.accept(printVisitor);\r
- sb.append(", ");\r
- b.valueType.accept(printVisitor);\r
- sb.append(")");\r
- return null;\r
- }\r
-\r
- };\r
-\r
- THashSet<Datatype> seen = new THashSet<Datatype>();\r
-\r
- private void collectRefs(Datatype dt) {\r
- if(dt instanceof RecordType || dt instanceof UnionType) {\r
- if(!seen.add(dt)) {\r
- if(!refs.containsKey(dt))\r
- refs.put(dt, "T" + refs.size());\r
- return;\r
- }\r
- }\r
- dt.accept(refCollectVisitor);\r
- }\r
-\r
- Visitor<Object> refCollectVisitor = new Visitor<Object>() {\r
-\r
- @Override\r
- public Object visit(ArrayType b) {\r
- collectRefs(b.componentType);\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(BooleanType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(DoubleType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(FloatType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(IntegerType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(ByteType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(LongType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(OptionalType b) {\r
- collectRefs(b.componentType);\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(RecordType b) {\r
- for(Component c : b.getComponents())\r
- collectRefs(c.type);\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(StringType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(UnionType b) {\r
- for(Component c : b.getComponents())\r
- collectRefs(c.type);\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(VariantType b) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object visit(MapType b) {\r
- collectRefs(b.keyType);\r
- collectRefs(b.valueType);\r
- return null;\r
- }\r
-\r
- };\r
-\r
- void printDt(Datatype dt) {\r
- collectRefs(dt);\r
- dt.accept(printVisitor);\r
- if(!refs.isEmpty()) {\r
- newLine();\r
- sb.append("where");\r
- ++indentation;\r
- refs.forEachEntry(new TObjectObjectProcedure<Datatype, String>() {\r
- @Override\r
- public boolean execute(Datatype a, String b) {\r
- newLine();\r
- sb.append(b).append(" = ");\r
- useRef = false;\r
- a.accept(printVisitor);\r
- return true;\r
- }\r
- });\r
- --indentation;\r
- refs.clear();\r
- }\r
- }\r
- \r
- public static String print(Datatype dt) {\r
- StringBuilder sb = new StringBuilder();\r
- new DataTypePrinter2(sb).printDt(dt);\r
- return sb.toString();\r
+
+ private DataTypePrinter2(StringBuilder sb) {
+ this.sb = sb;
+ }
+
+ void newLine() {
+ sb.append('\n');
+ for(int i=0;i<indentation;++i)
+ sb.append(" ");
+ }
+
+ boolean useRef = true;
+ Visitor<Object> printVisitor = new Visitor<Object>() {
+
+ @Override
+ public Object visit(ArrayType b) {
+ useRef = true;
+ sb.append("Array(");
+ b.componentType.accept(printVisitor);
+ sb.append(")");
+ return null;
+ }
+
+ @Override
+ public Object visit(BooleanType b) {
+ useRef = true;
+ sb.append("Boolean");
+ return null;
+ }
+
+ @Override
+ public Object visit(DoubleType b) {
+ useRef = true;
+ sb.append("Double");
+ return null;
+ }
+
+ @Override
+ public Object visit(FloatType b) {
+ useRef = true;
+ sb.append("Float");
+ return null;
+ }
+
+ @Override
+ public Object visit(IntegerType b) {
+ useRef = true;
+ sb.append("Integer");
+ return null;
+ }
+
+ @Override
+ public Object visit(ByteType b) {
+ useRef = true;
+ sb.append("Byte");
+ return null;
+ }
+
+ @Override
+ public Object visit(LongType b) {
+ useRef = true;
+ sb.append("Long");
+ return null;
+ }
+
+ @Override
+ public Object visit(OptionalType b) {
+ useRef = true;
+ sb.append("Optional(");
+ b.componentType.accept(printVisitor);
+ sb.append(")");
+ return null;
+ }
+
+ @Override
+ public Object visit(RecordType b) {
+ if(refs.containsKey(b) && useRef)
+ sb.append(refs.get(b));
+ else {
+ useRef = true;
+ sb.append("{");
+ ++indentation;
+ for(int i=0;i<b.getComponentCount();++i) {
+ if(i > 0)
+ sb.append(", ");
+ Component c = b.getComponent(i);
+ newLine();
+ sb.append(c.name);
+ sb.append(" : ");
+ c.type.accept(printVisitor);
+ }
+ --indentation;
+ newLine();
+ sb.append("}");
+ }
+ return null;
+ }
+
+ @Override
+ public Object visit(StringType b) {
+ useRef = true;
+ sb.append("String");
+ return null;
+ }
+
+ @Override
+ public Object visit(UnionType b) {
+ if(refs.containsKey(b) && useRef)
+ sb.append(refs.get(b));
+ else {
+ useRef = true;
+ ++indentation;
+ for(int i=0;i<b.getComponentCount();++i) {
+ newLine();
+ sb.append("| ");
+ Component c = b.getComponent(i);
+ sb.append(c.name);
+ sb.append(" ");
+ c.type.accept(printVisitor);
+ }
+ --indentation;
+ }
+ return null;
+ }
+
+ @Override
+ public Object visit(VariantType b) {
+ useRef = true;
+ sb.append("Variant");
+ return null;
+ }
+
+ @Override
+ public Object visit(MapType b) {
+ useRef = true;
+ sb.append("Map(");
+ b.keyType.accept(printVisitor);
+ sb.append(", ");
+ b.valueType.accept(printVisitor);
+ sb.append(")");
+ return null;
+ }
+
+ };
+
+ THashSet<Datatype> seen = new THashSet<Datatype>();
+
+ private void collectRefs(Datatype dt) {
+ if(dt instanceof RecordType || dt instanceof UnionType) {
+ if(!seen.add(dt)) {
+ if(!refs.containsKey(dt))
+ refs.put(dt, "T" + refs.size());
+ return;
+ }
+ }
+ dt.accept(refCollectVisitor);
+ }
+
+ Visitor<Object> refCollectVisitor = new Visitor<Object>() {
+
+ @Override
+ public Object visit(ArrayType b) {
+ collectRefs(b.componentType);
+ return null;
+ }
+
+ @Override
+ public Object visit(BooleanType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(DoubleType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(FloatType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(IntegerType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(ByteType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(LongType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(OptionalType b) {
+ collectRefs(b.componentType);
+ return null;
+ }
+
+ @Override
+ public Object visit(RecordType b) {
+ for(Component c : b.getComponents())
+ collectRefs(c.type);
+ return null;
+ }
+
+ @Override
+ public Object visit(StringType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(UnionType b) {
+ for(Component c : b.getComponents())
+ collectRefs(c.type);
+ return null;
+ }
+
+ @Override
+ public Object visit(VariantType b) {
+ return null;
+ }
+
+ @Override
+ public Object visit(MapType b) {
+ collectRefs(b.keyType);
+ collectRefs(b.valueType);
+ return null;
+ }
+
+ };
+
+ void printDt(Datatype dt) {
+ collectRefs(dt);
+ dt.accept(printVisitor);
+ if(!refs.isEmpty()) {
+ newLine();
+ sb.append("where");
+ ++indentation;
+ refs.forEachEntry(new TObjectObjectProcedure<Datatype, String>() {
+ @Override
+ public boolean execute(Datatype a, String b) {
+ newLine();
+ sb.append(b).append(" = ");
+ useRef = false;
+ a.accept(printVisitor);
+ return true;
+ }
+ });
+ --indentation;
+ refs.clear();
+ }
+ }
+
+ public static String print(Datatype dt) {
+ StringBuilder sb = new StringBuilder();
+ new DataTypePrinter2(sb).printDt(dt);
+ return sb.toString();