-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
+/*******************************************************************************
+ * Copyright (c) 2010 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
package org.simantics.databoard.parser.unparsing;
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectObjectProcedure;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-import org.simantics.databoard.type.ArrayType;\r
-import org.simantics.databoard.type.BooleanType;\r
-import org.simantics.databoard.type.ByteType;\r
-import org.simantics.databoard.type.Component;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.databoard.type.Datatype.Visitor;\r
-import org.simantics.databoard.type.DoubleType;\r
-import org.simantics.databoard.type.FloatType;\r
-import org.simantics.databoard.type.IntegerType;\r
-import org.simantics.databoard.type.LongType;\r
-import org.simantics.databoard.type.MapType;\r
-import org.simantics.databoard.type.OptionalType;\r
-import org.simantics.databoard.type.RecordType;\r
-import org.simantics.databoard.type.StringType;\r
-import org.simantics.databoard.type.UnionType;\r
-import org.simantics.databoard.type.VariantType;\r
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
+import org.simantics.databoard.type.ArrayType;
+import org.simantics.databoard.type.BooleanType;
+import org.simantics.databoard.type.ByteType;
+import org.simantics.databoard.type.Component;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.type.Datatype.Visitor;
+import org.simantics.databoard.type.DoubleType;
+import org.simantics.databoard.type.FloatType;
+import org.simantics.databoard.type.IntegerType;
+import org.simantics.databoard.type.LongType;
+import org.simantics.databoard.type.MapType;
+import org.simantics.databoard.type.OptionalType;
+import org.simantics.databoard.type.RecordType;
+import org.simantics.databoard.type.StringType;
+import org.simantics.databoard.type.UnionType;
+import org.simantics.databoard.type.VariantType;
/**
public class DataTypePrinter2 {
StringBuilder sb;
- int indentation = 0;\r
+ int indentation = 0;
THashMap<Datatype, String> refs = new THashMap<Datatype, String>();
-\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();
}
}