1 /*******************************************************************************
2 * Copyright (c) 2010 Association for Decentralized Information Management in
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.databoard.parser.unparsing;
14 import java.util.List;
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;
30 * Converts abstract syntax tree of data type to string.
32 * @author Hannu Niemistö
34 public class DataTypePrinter {
36 StringBuilder stringBuilder;
38 boolean linefeed = true;
39 /** Optional data type repository. If <code>null</code> refered types are inlined */
40 DataTypeRepository repo;
42 public DataTypePrinter(StringBuilder stringBuilder) {
43 this.stringBuilder = stringBuilder;
46 public DataTypeRepository getDataTypeRepository() {
50 public void setDataTypeRepository(DataTypeRepository repo) {
54 public StringBuilder getStringBuilder() {
58 public void setStringBuilder(StringBuilder stringBuilder) {
59 this.stringBuilder = stringBuilder;
62 private void indent() {
63 for(int i=0;i<indentation;++i)
64 stringBuilder.append(" ");
67 public void setLinefeed(boolean linefeed) {
68 this.linefeed = linefeed;
71 public void visit(AstTypeDefinition definition) {
73 stringBuilder.append("type ");
74 stringBuilder.append(definition.name);
75 stringBuilder.append(" = ");
76 visit(definition.type);
77 stringBuilder.append("\n");
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);
93 throw new AssertionError("Unhandled abstract syntax tree node type.");
96 public void visit(AstArrayType type) {
97 visit(type.componentType);
98 if(type.minLength == null) {
99 if(type.maxLength == null)
100 stringBuilder.append("[]");
102 stringBuilder.append("[..");
103 stringBuilder.append(type.maxLength);
104 stringBuilder.append(']');
108 if(type.maxLength == null) {
109 stringBuilder.append('[');
110 stringBuilder.append(type.minLength);
111 stringBuilder.append("..]");
114 stringBuilder.append('[');
115 if(type.minLength.equals(type.maxLength))
116 stringBuilder.append(type.minLength);
118 stringBuilder.append(type.minLength);
119 stringBuilder.append("..");
120 stringBuilder.append(type.maxLength);
122 stringBuilder.append(']');
127 public void visit(AstAttribute attribute) {
128 stringBuilder.append(attribute.key);
129 stringBuilder.append("=\"");
130 stringBuilder.append(StringEscapeUtils.escape(attribute.value));
131 stringBuilder.append('"');
134 public void visit(AstComponent component) {
135 stringBuilder.append(component.name);
136 stringBuilder.append(" : ");
137 visit(component.type);
140 public void visit(AstRecordType type) {
142 stringBuilder.append("referable ");
143 if(type.components.isEmpty()) {
144 stringBuilder.append("{}");
147 stringBuilder.append('{');
148 if (linefeed) stringBuilder.append('\n');
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');
158 if (linefeed) indent();
159 stringBuilder.append('}');
163 public void visit(AstTupleType type) {
164 stringBuilder.append('(');
165 for(int i=0;i<type.components.size();++i) {
167 stringBuilder.append(", ");
168 visit(type.components.get(i));
170 stringBuilder.append(')');
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) {
182 stringBuilder.append(", ");
185 for(AstAttribute attribute : type.attributes) {
189 stringBuilder.append(", ");
192 stringBuilder.append(')');
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);
205 for(AstComponent component : type.components) {
206 if (linefeed) stringBuilder.append('\n');
208 stringBuilder.append("| ");
209 stringBuilder.append(component.name);
210 stringBuilder.append(' ');
212 visit(component.type);
223 public void print(Datatype type) {
224 DataTypeToAst converter = new DataTypeToAst(new DataTypeRepository());
225 AstType astType = converter.visit(type);
230 * Print type definitions and definitions of referred types
233 public void printDefinitions(Datatype type) {
234 DataTypeToAst converter = new DataTypeToAst(new DataTypeRepository());
235 visit(converter.visit(type));
237 List<AstTypeDefinition> definitions = converter.getTypeDefinitions();
238 for(AstTypeDefinition def : definitions)
244 public String toString() {
245 return stringBuilder.toString();
249 * Converts a data type to string.
252 * @param linefeed if true add line feed
253 * @return data type as string
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();