]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/parser/unparsing/DataTypePrinter2.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / parser / unparsing / DataTypePrinter2.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.parser.unparsing;
13
14 import gnu.trove.map.hash.THashMap;
15 import gnu.trove.procedure.TObjectObjectProcedure;
16 import gnu.trove.set.hash.THashSet;
17
18 import org.simantics.databoard.type.ArrayType;
19 import org.simantics.databoard.type.BooleanType;
20 import org.simantics.databoard.type.ByteType;
21 import org.simantics.databoard.type.Component;
22 import org.simantics.databoard.type.Datatype;
23 import org.simantics.databoard.type.Datatype.Visitor;
24 import org.simantics.databoard.type.DoubleType;
25 import org.simantics.databoard.type.FloatType;
26 import org.simantics.databoard.type.IntegerType;
27 import org.simantics.databoard.type.LongType;
28 import org.simantics.databoard.type.MapType;
29 import org.simantics.databoard.type.OptionalType;
30 import org.simantics.databoard.type.RecordType;
31 import org.simantics.databoard.type.StringType;
32 import org.simantics.databoard.type.UnionType;
33 import org.simantics.databoard.type.VariantType;
34
35
36 /**
37  * @author Hannu Niemistö
38  */
39 public class DataTypePrinter2 {
40
41     StringBuilder sb;
42     int indentation = 0;
43     THashMap<Datatype, String> refs = new THashMap<Datatype, String>();
44
45     private DataTypePrinter2(StringBuilder sb) {
46         this.sb = sb;
47     }
48
49     void newLine() {
50         sb.append('\n');
51         for(int i=0;i<indentation;++i)
52             sb.append("    ");
53     }
54     
55     boolean useRef = true;
56     Visitor<Object> printVisitor = new Visitor<Object>() {
57
58         @Override
59         public Object visit(ArrayType b) {
60             useRef = true;
61             sb.append("Array(");
62             b.componentType.accept(printVisitor);
63             sb.append(")");
64             return null;
65         }
66
67         @Override
68         public Object visit(BooleanType b) {
69             useRef = true;
70             sb.append("Boolean");
71             return null;
72         }
73
74         @Override
75         public Object visit(DoubleType b) {
76             useRef = true;
77             sb.append("Double");
78             return null;
79         }
80
81         @Override
82         public Object visit(FloatType b) {
83             useRef = true;
84             sb.append("Float");
85             return null;
86         }
87
88         @Override
89         public Object visit(IntegerType b) {
90             useRef = true;
91             sb.append("Integer");
92             return null;
93         }
94
95         @Override
96         public Object visit(ByteType b) {
97             useRef = true;
98             sb.append("Byte");
99             return null;
100         }
101
102         @Override
103         public Object visit(LongType b) {
104             useRef = true;
105             sb.append("Long");
106             return null;
107         }
108
109         @Override
110         public Object visit(OptionalType b) {
111             useRef = true;
112             sb.append("Optional(");
113             b.componentType.accept(printVisitor);
114             sb.append(")");
115             return null;
116         }
117
118         @Override
119         public Object visit(RecordType b) {
120             if(refs.containsKey(b) && useRef)
121                 sb.append(refs.get(b));
122             else {
123                 useRef = true;
124                 sb.append("{");
125                 ++indentation;
126                 for(int i=0;i<b.getComponentCount();++i) {
127                     if(i > 0)
128                         sb.append(", ");
129                     Component c = b.getComponent(i);
130                     newLine();
131                     sb.append(c.name);
132                     sb.append(" : ");
133                     c.type.accept(printVisitor);
134                 }
135                 --indentation;
136                 newLine();
137                 sb.append("}");
138             }
139             return null;
140         }
141
142         @Override
143         public Object visit(StringType b) {
144             useRef = true;
145             sb.append("String");
146             return null;
147         }
148
149         @Override
150         public Object visit(UnionType b) {
151             if(refs.containsKey(b) && useRef)
152                 sb.append(refs.get(b));
153             else {
154                 useRef = true;
155                 ++indentation;
156                 for(int i=0;i<b.getComponentCount();++i) {
157                     newLine();
158                     sb.append("| ");
159                     Component c = b.getComponent(i);
160                     sb.append(c.name);
161                     sb.append(" ");
162                     c.type.accept(printVisitor);
163                 }
164                 --indentation;
165             }
166             return null;
167         }
168
169         @Override
170         public Object visit(VariantType b) {
171             useRef = true;
172             sb.append("Variant");
173             return null;
174         }
175
176         @Override
177         public Object visit(MapType b) {
178             useRef = true;
179             sb.append("Map(");
180             b.keyType.accept(printVisitor);
181             sb.append(", ");
182             b.valueType.accept(printVisitor);
183             sb.append(")");
184             return null;
185         }
186
187     };
188
189     THashSet<Datatype> seen = new THashSet<Datatype>();
190
191     private void collectRefs(Datatype dt) {
192         if(dt instanceof RecordType || dt instanceof UnionType) {
193             if(!seen.add(dt)) {
194                 if(!refs.containsKey(dt))
195                     refs.put(dt, "T" + refs.size());
196                 return;
197             }
198         }
199         dt.accept(refCollectVisitor);
200     }
201
202     Visitor<Object> refCollectVisitor = new Visitor<Object>() {
203
204         @Override
205         public Object visit(ArrayType b) {
206             collectRefs(b.componentType);
207             return null;
208         }
209
210         @Override
211         public Object visit(BooleanType b) {
212             return null;
213         }
214
215         @Override
216         public Object visit(DoubleType b) {
217             return null;
218         }
219
220         @Override
221         public Object visit(FloatType b) {
222             return null;
223         }
224
225         @Override
226         public Object visit(IntegerType b) {
227             return null;
228         }
229
230         @Override
231         public Object visit(ByteType b) {
232             return null;
233         }
234
235         @Override
236         public Object visit(LongType b) {
237             return null;
238         }
239
240         @Override
241         public Object visit(OptionalType b) {
242             collectRefs(b.componentType);
243             return null;
244         }
245
246         @Override
247         public Object visit(RecordType b) {
248             for(Component c : b.getComponents())
249                 collectRefs(c.type);
250             return null;
251         }
252
253         @Override
254         public Object visit(StringType b) {
255             return null;
256         }
257
258         @Override
259         public Object visit(UnionType b) {
260             for(Component c : b.getComponents())
261                 collectRefs(c.type);
262             return null;
263         }
264
265         @Override
266         public Object visit(VariantType b) {
267             return null;
268         }
269
270         @Override
271         public Object visit(MapType b) {
272             collectRefs(b.keyType);
273             collectRefs(b.valueType);
274             return null;
275         }
276
277     };
278
279     void printDt(Datatype dt) {
280         collectRefs(dt);
281         dt.accept(printVisitor);
282         if(!refs.isEmpty()) {
283             newLine();
284             sb.append("where");
285             ++indentation;
286             refs.forEachEntry(new TObjectObjectProcedure<Datatype, String>() {
287                 @Override
288                 public boolean execute(Datatype a, String b) {
289                     newLine();
290                     sb.append(b).append(" = ");
291                     useRef = false;
292                     a.accept(printVisitor);
293                     return true;
294                 }
295             });
296             --indentation;
297             refs.clear();
298         }
299     }
300     
301     public static String print(Datatype dt) {
302         StringBuilder sb = new StringBuilder();
303         new DataTypePrinter2(sb).printDt(dt);
304         return sb.toString();
305     }
306
307 }