]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/parser/unparsing/DataTypePrinter.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / parser / unparsing / DataTypePrinter.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 java.util.List;
15
16 import org.simantics.databoard.parser.StringEscapeUtils;
17 import org.simantics.databoard.parser.ast.type.AstArrayType;
18 import org.simantics.databoard.parser.ast.type.AstAttribute;
19 import org.simantics.databoard.parser.ast.type.AstComponent;
20 import org.simantics.databoard.parser.ast.type.AstRecordType;
21 import org.simantics.databoard.parser.ast.type.AstTupleType;
22 import org.simantics.databoard.parser.ast.type.AstType;
23 import org.simantics.databoard.parser.ast.type.AstTypeDefinition;
24 import org.simantics.databoard.parser.ast.type.AstTypeReference;
25 import org.simantics.databoard.parser.ast.type.AstUnionType;
26 import org.simantics.databoard.parser.repository.DataTypeRepository;
27 import org.simantics.databoard.type.Datatype;
28
29 /**
30  * Converts abstract syntax tree of data type to string.
31  * 
32  * @author Hannu Niemistö
33  */
34 public class DataTypePrinter {
35         
36         StringBuilder stringBuilder;
37         int indentation = 0;
38         boolean linefeed = true;
39         /** Optional data type repository. If <code>null</code> refered types are inlined */
40         DataTypeRepository repo;        
41         
42         public DataTypePrinter(StringBuilder stringBuilder) {
43                 this.stringBuilder = stringBuilder;
44         }
45         
46         public DataTypeRepository getDataTypeRepository() {
47                 return repo;
48         }
49
50         public void setDataTypeRepository(DataTypeRepository repo) {
51                 this.repo = repo;
52         }
53
54         public StringBuilder getStringBuilder() {
55                 return stringBuilder;
56         }
57
58         public void setStringBuilder(StringBuilder stringBuilder) {
59                 this.stringBuilder = stringBuilder;
60         }
61
62         private void indent() {
63                 for(int i=0;i<indentation;++i)
64                         stringBuilder.append("  ");
65         }
66         
67         public void setLinefeed(boolean linefeed) {
68                 this.linefeed = linefeed;
69         }
70         
71         public void visit(AstTypeDefinition definition) {
72                 indent();
73                 stringBuilder.append("type ");
74                 stringBuilder.append(definition.name);
75                 stringBuilder.append(" = ");
76                 visit(definition.type);
77                 stringBuilder.append("\n");
78         }
79         
80         public void visit(AstType type) {
81                 Class<?> clazz = type.getClass();
82                 if(clazz == AstArrayType.class)
83                         visit((AstArrayType)type);
84                 else if(clazz == AstRecordType.class)
85                         visit((AstRecordType)type);
86                 else if(clazz == AstTupleType.class)
87                         visit((AstTupleType)type);
88                 else if(clazz == AstTypeReference.class)
89                         visit((AstTypeReference)type);
90                 else if(clazz == AstUnionType.class)
91                         visit((AstUnionType)type);
92                 else
93                         throw new AssertionError("Unhandled abstract syntax tree node type.");
94         }
95         
96         public void visit(AstArrayType type) {
97                 visit(type.componentType);
98                 if(type.minLength == null) {
99                         if(type.maxLength == null)
100                                 stringBuilder.append("[]");
101                         else {
102                                 stringBuilder.append("[..");
103                                 stringBuilder.append(type.maxLength);
104                                 stringBuilder.append(']');
105                         }
106                 }
107                 else  {
108                         if(type.maxLength == null) {
109                                 stringBuilder.append('[');
110                                 stringBuilder.append(type.minLength);
111                                 stringBuilder.append("..]");
112                         }
113                         else {
114                                 stringBuilder.append('[');
115                                 if(type.minLength.equals(type.maxLength)) 
116                                         stringBuilder.append(type.minLength);
117                                 else {
118                                         stringBuilder.append(type.minLength);
119                                         stringBuilder.append("..");
120                                         stringBuilder.append(type.maxLength);
121                                 }
122                                 stringBuilder.append(']');
123                         }
124                 }
125         }
126         
127         public void visit(AstAttribute attribute) {
128                 stringBuilder.append(attribute.key);
129                 stringBuilder.append("=\"");
130                 stringBuilder.append(StringEscapeUtils.escape(attribute.value));
131                 stringBuilder.append('"');
132         }
133         
134         public void visit(AstComponent component) {
135                 stringBuilder.append(component.name);
136                 stringBuilder.append(" : ");
137                 visit(component.type);
138         }
139         
140         public void visit(AstRecordType type) {
141                 if(type.referable)
142                         stringBuilder.append("referable ");
143                 if(type.components.isEmpty()) {
144                         stringBuilder.append("{}");
145                 }
146                 else {
147                         stringBuilder.append('{');
148                         if (linefeed) stringBuilder.append('\n');
149                         indentation += 2;
150                         for(int i=0;i<type.components.size();++i) {
151                                 if (linefeed) indent();
152                                 visit(type.components.get(i));
153                                 if(i < type.components.size()-1)
154                                         stringBuilder.append(',');
155                                 if (linefeed) stringBuilder.append('\n');
156                         }
157                         indentation -= 2;
158                         if (linefeed) indent();
159                         stringBuilder.append('}');
160                 }
161         }
162         
163         public void visit(AstTupleType type) {
164                 stringBuilder.append('(');
165                 for(int i=0;i<type.components.size();++i) {
166                         if(i > 0)
167                                 stringBuilder.append(", ");
168                         visit(type.components.get(i));
169                 }
170                 stringBuilder.append(')');
171         }
172         
173         public void visit(AstTypeReference type) {
174                 stringBuilder.append(type.name);
175                 if(!type.parameters.isEmpty() || !type.attributes.isEmpty()) {                  
176                         stringBuilder.append('(');
177                         boolean first = true;
178                         for(AstType parameter : type.parameters) {
179                                 if(first)
180                                         first = false;
181                                 else
182                                         stringBuilder.append(", ");
183                                 visit(parameter);
184                         }
185                         for(AstAttribute attribute : type.attributes) {
186                                 if(first)
187                                         first = false;
188                                 else
189                                         stringBuilder.append(", ");
190                                 visit(attribute);
191                         }
192                         stringBuilder.append(')');                      
193                 }
194         }
195         
196         public void visit(AstUnionType type) {
197                 if(type.components.size() == 1) {
198                         stringBuilder.append("| ");
199                         stringBuilder.append(type.components.get(0).name);
200                         stringBuilder.append(' ');
201                         visit(type.components.get(0).type);
202                 }
203                 else {
204                         ++indentation;
205                         for(AstComponent component : type.components) {
206                                 if (linefeed) stringBuilder.append('\n');
207                                 indent();                       
208                                 stringBuilder.append("| ");
209                                 stringBuilder.append(component.name);
210                                 stringBuilder.append(' ');
211                                 ++indentation;
212                                 visit(component.type);
213                                 --indentation;
214                         }
215                 }
216                 --indentation;
217         }
218
219         /** 
220          * Print type
221          * @param type
222          */
223         public void print(Datatype type) {
224                 DataTypeToAst converter = new DataTypeToAst(new DataTypeRepository());
225                 AstType astType = converter.visit(type); 
226                 visit(astType);
227         }
228         
229         /**
230          * Print type definitions and definitions of referred types
231          * @param type
232          */
233         public void printDefinitions(Datatype type) {
234                 DataTypeToAst converter = new DataTypeToAst(new DataTypeRepository());          
235                 visit(converter.visit(type));
236                 
237                 List<AstTypeDefinition> definitions = converter.getTypeDefinitions();
238                 for(AstTypeDefinition def : definitions)
239                         visit(def);
240         }
241         
242         
243         @Override
244         public String toString() {
245                 return stringBuilder.toString();
246         }
247         
248         /**
249          * Converts a data type to string.
250          * 
251          * @param dataType
252          * @param linefeed if true add line feed
253          * @return data type as string 
254          */
255         public static String toString(Datatype dataType, boolean linefeed) {
256                 DataTypePrinter printer = new DataTypePrinter( new StringBuilder() );
257                 printer.setLinefeed( linefeed );
258                 printer.print(dataType);
259                 return printer.toString();
260         }
261         
262 }