/******************************************************************************* * 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; 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; /** * @author Hannu Niemistö */ public class DataTypePrinter2 { StringBuilder sb; int indentation = 0; THashMap refs = new THashMap(); private DataTypePrinter2(StringBuilder sb) { this.sb = sb; } void newLine() { sb.append('\n'); for(int i=0;i printVisitor = new Visitor() { @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 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 seen = new THashSet(); 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 refCollectVisitor = new Visitor() { @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() { @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(); } }