]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/parser/unparsing/DataTypeToAst.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / parser / unparsing / DataTypeToAst.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.set.hash.THashSet;
15
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.simantics.databoard.parser.ast.type.AstArrayType;
20 import org.simantics.databoard.parser.ast.type.AstComponent;
21 import org.simantics.databoard.parser.ast.type.AstRecordType;
22 import org.simantics.databoard.parser.ast.type.AstTupleType;
23 import org.simantics.databoard.parser.ast.type.AstType;
24 import org.simantics.databoard.parser.ast.type.AstTypeDefinition;
25 import org.simantics.databoard.parser.ast.type.AstTypeReference;
26 import org.simantics.databoard.parser.ast.type.AstUnionType;
27 import org.simantics.databoard.parser.repository.DataTypeRepository;
28 import org.simantics.databoard.type.ArrayType;
29 import org.simantics.databoard.type.BooleanType;
30 import org.simantics.databoard.type.ByteType;
31 import org.simantics.databoard.type.Component;
32 import org.simantics.databoard.type.Datatype;
33 import org.simantics.databoard.type.Datatype.Visitor;
34 import org.simantics.databoard.type.DoubleType;
35 import org.simantics.databoard.type.FloatType;
36 import org.simantics.databoard.type.IntegerType;
37 import org.simantics.databoard.type.LongType;
38 import org.simantics.databoard.type.MapType;
39 import org.simantics.databoard.type.NumberType;
40 import org.simantics.databoard.type.OptionalType;
41 import org.simantics.databoard.type.RecordType;
42 import org.simantics.databoard.type.StringType;
43 import org.simantics.databoard.type.UnionType;
44 import org.simantics.databoard.type.VariantType;
45
46 /**
47  * Converts data type to abstract syntax tree.
48  * 
49  * @author Hannu Niemistö
50  */
51 public class DataTypeToAst implements Visitor<AstType> {
52
53         List<AstTypeDefinition> typeDefinitions = new ArrayList<AstTypeDefinition>();
54         DataTypeRepository repo = new DataTypeRepository();
55         THashSet<Datatype> underConstruction = new THashSet<Datatype>();
56
57         int id = 0;
58
59         public DataTypeToAst(DataTypeRepository repo) {
60                 this.repo = repo;
61         }
62         
63         private String freshTypeName() {
64                 return "Temp" + (++id);
65         }
66         
67         public AstType addDefinition(String name, Datatype type) {
68                 repo.add(name, type);
69                 AstType ast = type.accept(this);                
70                 typeDefinitions.add(new AstTypeDefinition(name, type.accept(this)));
71                 return ast;
72         }
73         
74         public AstType visit(Datatype type) {
75                 if(repo.contains(type))
76                         return new AstTypeReference(repo.get(type));
77                 if(underConstruction.contains(type)) {
78                         String name = repo.get(type);
79                         if (name==null) {
80                                 name = freshTypeName();
81                                 repo.add(name, type);
82                         }
83                         underConstruction.remove(type);
84                         return new AstTypeReference(name);
85                 }
86                 else {
87                         underConstruction.add(type);
88                         AstType ast = type.accept(this);
89                         if(!underConstruction.remove(type)) {
90                                 String name = repo.get(type);
91                                 typeDefinitions.add(new AstTypeDefinition(name, ast));
92                                 return new AstTypeReference(name);
93                         }
94                         else
95                                 return ast;
96                 }
97         }
98         
99         @Override
100         public AstType visit(ArrayType b) {
101                 return new AstArrayType(visit(b.componentType), 
102                                 b.getLength()==null ? null : b.getLength().getLower().smallestIncludedInteger(),
103                             b.getLength()==null ? null : b.getLength().getUpper().greatestIncludedInteger());
104         }
105
106         @Override
107         public AstType visit(BooleanType b) {
108                 return new AstTypeReference("Boolean");
109         }
110
111         @Override
112         public AstType visit(DoubleType b) {
113                 AstTypeReference ref = new AstTypeReference("Double");
114                 // XXX
115                 if( b.metadata.containsKey( NumberType.KEY_RANGE ) )
116                         ref.addAttribute("range", b.metadata.get( NumberType.KEY_RANGE ) );             
117                 if( b.metadata.containsKey( NumberType.KEY_UNIT ) )
118                         ref.addAttribute("unit", b.metadata.get( NumberType.KEY_UNIT ));
119                 return ref;
120         }
121
122         @Override
123         public AstType visit(FloatType b) {
124                 AstTypeReference ref = new AstTypeReference("Float");
125                 // XXX
126                 if( b.metadata.containsKey( NumberType.KEY_RANGE ) )
127                         ref.addAttribute("range", b.metadata.get( NumberType.KEY_RANGE ) );             
128                 if( b.metadata.containsKey( NumberType.KEY_UNIT ) )
129                         ref.addAttribute("unit", b.metadata.get( NumberType.KEY_UNIT ));
130                 return ref;
131         }
132
133         @Override
134         public AstType visit(IntegerType b) {
135                 AstTypeReference ref = new AstTypeReference("Integer");
136                 // XXX
137                 if( b.metadata.containsKey( NumberType.KEY_RANGE ) )
138                         ref.addAttribute("range", b.metadata.get( NumberType.KEY_RANGE ) );             
139                 if( b.metadata.containsKey( NumberType.KEY_UNIT ) )
140                         ref.addAttribute("unit", b.metadata.get( NumberType.KEY_UNIT ));
141                 return ref;
142         }
143
144         @Override
145         public AstType visit(ByteType b) {
146                 return new AstTypeReference("Byte");
147         }
148
149         @Override
150         public AstType visit(LongType b) {
151                 AstTypeReference ref = new AstTypeReference("Long");
152                 // XXX
153                 if( b.metadata.containsKey( NumberType.KEY_RANGE ) )
154                         ref.addAttribute("range", b.metadata.get( NumberType.KEY_RANGE ) );             
155                 if( b.metadata.containsKey( NumberType.KEY_UNIT ) )
156                         ref.addAttribute("unit", b.metadata.get( NumberType.KEY_UNIT ));
157                 return ref;
158         }
159
160         @Override
161         public AstType visit(OptionalType b) {
162                 return new AstTypeReference("Optional", visit(b.getComponentType()));
163         }
164
165         @Override
166         public AstType visit(RecordType b) {
167                 if(b.isTupleType()) {
168                         AstTupleType tuple = new AstTupleType(new ArrayList<AstType>(b.getComponentCount()));
169                         for(Component component : b.getComponents()) 
170                                 tuple.addComponent(visit(component.type));
171                         return tuple;
172                 }
173                 else {
174                         AstRecordType record = new AstRecordType(b.isReferable(), new ArrayList<AstComponent>(b.getComponentCount()));
175                         for(Component component : b.getComponents()) 
176                                 record.addComponent(component.name, visit(component.type));
177                         return record;
178                 }
179         }
180
181         @Override
182         public AstType visit(StringType b) {
183                 AstTypeReference ref = new AstTypeReference("String");
184                 // XXX
185                 if( b.metadata.containsKey( StringType.KEY_MIMETYPE ) )
186                         ref.addAttribute("mimeType", b.metadata.get( StringType.KEY_MIMETYPE ));
187                 if( b.metadata.containsKey( StringType.KEY_LENGTH ) )
188                         ref.addAttribute("length", b.metadata.get( StringType.KEY_LENGTH ));
189                 if( b.metadata.containsKey( StringType.KEY_PATTERN ))
190                         ref.addAttribute("pattern", b.metadata.get( StringType.KEY_PATTERN ));
191                 return ref;
192         }
193
194         @Override
195         public AstType visit(UnionType b) {
196                 AstUnionType union = new AstUnionType(new ArrayList<AstComponent>(b.components.length));
197                 for(Component component : b.components) 
198                         union.addComponent(component.name, visit(component.type));
199                 return union;
200         }       
201         
202         @Override
203         public AstType visit(VariantType b) {
204                 AstTypeReference ref = new AstTypeReference("Variant");
205                 return ref;
206         }
207         
208         public List<AstTypeDefinition> getTypeDefinitions() {
209                 return typeDefinitions;
210         }
211
212         @Override
213         public AstType visit(MapType b) {
214                 AstTypeReference ref = new AstTypeReference("Map", visit(b.keyType), visit(b.valueType));
215                 return ref;
216         }
217         
218 }