Package: VdmTypeCreator

VdmTypeCreator

nameinstructionbranchcomplexitylinemethod
VdmTypeCreator(UmlConsole)
M: 67 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
convert(Property)
M: 76 C: 0
0%
M: 16 C: 0
0%
M: 9 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%
convert(String, String)
M: 177 C: 0
0%
M: 26 C: 0
0%
M: 14 C: 0
0%
M: 32 C: 0
0%
M: 1 C: 0
0%
convert(Type)
M: 112 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 26 C: 0
0%
M: 1 C: 0
0%
convertBasicType(String)
M: 61 C: 0
0%
M: 16 C: 0
0%
M: 9 C: 0
0%
M: 18 C: 0
0%
M: 1 C: 0
0%
convertGeneric(String)
M: 86 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 13 C: 0
0%
M: 1 C: 0
0%
createEnumeration(Enumeration)
M: 49 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
createRecord(Class)
M: 44 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
remapUmlTypes(String)
M: 57 C: 0
0%
M: 16 C: 0
0%
M: 9 C: 0
0%
M: 17 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 16 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * #%~
3: * UML2 Translator
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.ide.plugins.uml2.uml2vdm;
23:
24: import java.io.File;
25: import java.util.Arrays;
26: import java.util.HashSet;
27: import java.util.List;
28: import java.util.Set;
29: import java.util.Vector;
30:
31: import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
32: import org.eclipse.uml2.uml.Class;
33: import org.eclipse.uml2.uml.Enumeration;
34: import org.eclipse.uml2.uml.EnumerationLiteral;
35: import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
36: import org.eclipse.uml2.uml.Property;
37: import org.eclipse.uml2.uml.Type;
38: import org.overture.ast.assistant.pattern.PTypeList;
39: import org.overture.ast.factory.AstFactory;
40: import org.overture.ast.lex.LexLocation;
41: import org.overture.ast.lex.LexNameToken;
42: import org.overture.ast.lex.LexQuoteToken;
43: import org.overture.ast.types.AFieldField;
44: import org.overture.ast.types.PType;
45: import org.overture.ide.plugins.uml2.UmlConsole;
46: import org.overture.ide.plugins.uml2.vdm2uml.UmlTypeCreatorBase;
47:
48: public class VdmTypeCreator
49: {
50:         final Set<String> basicTypes = new HashSet<String>(Arrays.asList(new String[] {
51:                         "bool", "char", "token", "int", "nat", "nat1", "rat", "real" }));
52:         final String UNION_TYPE = "Union<";
53:         final String MAP_TYPE = "Map<";
54:         final String SET_TYPE = "Set<";
55:         final String SEQ_TYPE = "Seq<";
56:         final String PRODUCT_TYPE = "Product<";
57:         final String OPTIONAL_TYPE = "Optional<";
58:         final String INMAP_TYPE = "InMap<";
59:
60:         final static LexLocation location = new LexLocation(new File("generated"), "generating", 0, 0, 0, 0, 0, 0);
61:         private UmlConsole console;
62:
63:         public VdmTypeCreator(UmlConsole console)
64:         {
65:                 this.console = console;
66:         }
67:
68:         public PType convert(Property p)
69:         {
70:                 PType type = convert(p.getType());
71:•                if (p.getUpper() == LiteralUnlimitedNatural.UNLIMITED)
72:                 {
73:•                        if (p.isOrdered())
74:                         {
75:•                                if (p.getLower() == 0)
76:                                 {
77:                                         type = AstFactory.newASeqSeqType(location, type);
78:•                                } else if (p.getLower() == 1)
79:                                 {
80:                                         type = AstFactory.newASeq1SeqType(location, type);
81:                                 }
82:                         } else
83:                         {
84:                                 type = AstFactory.newASetSetType(location, type);
85:                         }
86:•                } else if (p.getLower() == 0 && p.getUpper() == 1)
87:                 {
88:                         type = AstFactory.newAOptionalType(location, type);
89:                 }
90:
91:•                if (p.getQualifiers().size() == 1)
92:                 {
93:                         Property qualifier = p.getQualifiers().get(0);
94:                         PType fromType = convert(qualifier);
95:•                        if (p.isUnique())
96:                         {
97:                                 type = AstFactory.newAInMapMapType(location, fromType, type);
98:                         } else
99:                         {
100:                                 type = AstFactory.newAMapMapType(location, fromType, type);
101:                         }
102:                 }
103:                 return type;
104:         }
105:
106:         public PType convert(Type type)
107:         {
108:                 try
109:                 {
110:•                        if (type == null)
111:                         {
112:                                 console.err.println("Found no type. Inserting an \"?\" type as a replacement");
113:                                 return convert(UmlTypeCreatorBase.ANY_TYPE, null);
114:                         }
115:                         String module = null;
116:•                        if (type.getNamespace() != null
117:•                                        && type.getNamespace() instanceof Class)
118:                         {
119:                                 module = type.getNamespace().getName();
120:                         }
121:
122:•                        if (type.getName() == null && type instanceof MinimalEObjectImpl)
123:                         {
124:                                 java.lang.reflect.Field f = MinimalEObjectImpl.class.getDeclaredField("eStorage");
125:                                 f.setAccessible(true);
126:                                 String storageUri = "" + f.get(type);
127:                                 System.out.println(storageUri);
128:                                 int index = storageUri.lastIndexOf("#");
129:•                                if (index == -1)
130:                                 {
131:                                         console.err.println("Could not decode \"" + storageUri
132:                                                         + "\" inseting an \"?\" type as a replacement");
133:                                         return convert(UmlTypeCreatorBase.ANY_TYPE, null);
134:                                 }
135:                                 String typeName = storageUri.substring(index + 1);
136:                                 return convert(remapUmlTypes(typeName), module);
137:•                        } else if (type.getName() == null)
138:                         {
139:                                 console.err.println("Type has no name. Inserting an \"?\" type as a replacement");
140:                                 return convert(UmlTypeCreatorBase.ANY_TYPE, null);
141:                         }
142:
143:                         return convert(type.getName(), module);
144:                 } catch (Exception e)
145:                 {
146:                         e.printStackTrace();
147:                         return null;
148:                 }
149:         }
150:
151:         private String remapUmlTypes(String name)
152:         {
153:•                if (name.equalsIgnoreCase("Integer"))
154:                 {
155:                         return "int";
156:•                } else if (name.equalsIgnoreCase("Boolean")
157:•                                || name.equalsIgnoreCase("float")
158:•                                || name.equalsIgnoreCase("long"))
159:                 {
160:                         return "bool";
161:•                } else if (name.equalsIgnoreCase("short")
162:•                                || name.equalsIgnoreCase("byte"))
163:                 {
164:                         return "nat";
165:•                } else if (name.equalsIgnoreCase("String"))
166:                 {
167:                         return "Seq<Char>";
168:•                } else if (name.equalsIgnoreCase("Double"))
169:                 {
170:                         return "real";
171:                 }
172:
173:                 console.err.println("Could not match UML type \""
174:                                 + name
175:                                 + "\" with a VDM type. Inserting an \"?\" type as a replacement");
176:                 return UmlTypeCreatorBase.ANY_TYPE;
177:         }
178:
179:         public PType convert(String type, String module)
180:         {
181:
182:•                if (basicTypes.contains(type.toLowerCase()))
183:                 {
184:                         return convertBasicType(type);
185:•                } else if (type.equals(UmlTypeCreatorBase.VOID_TYPE))
186:                 {
187:                         return AstFactory.newAVoidReturnType(location);
188:•                } else if (type.equals(UmlTypeCreatorBase.ANY_TYPE))
189:                 {
190:                         return AstFactory.newAUnknownType(location);
191:•                } else if (type.startsWith(UNION_TYPE))
192:                 {
193:                         return AstFactory.newAUnionType(location, convertGeneric(type));
194:•                } else if (type.startsWith(PRODUCT_TYPE))
195:                 {
196:                         return AstFactory.newAProductType(location, convertGeneric(type));
197:•                } else if (type.startsWith(MAP_TYPE))
198:                 {
199:                         List<PType> types = convertGeneric(type);
200:                         return AstFactory.newAMapMapType(location, types.get(0), types.get(1));
201:•                } else if (type.startsWith(INMAP_TYPE))
202:                 {
203:                         List<PType> types = convertGeneric(type);
204:                         return AstFactory.newAInMapMapType(location, types.get(0), types.get(1));
205:•                } else if (type.startsWith(SET_TYPE))
206:                 {
207:                         return AstFactory.newASetSetType(location, convertGeneric(type).get(0));
208:•                } else if (type.startsWith(SEQ_TYPE))
209:                 {
210:                         return AstFactory.newASeqSeqType(location, convertGeneric(type).get(0));
211:•                } else if (type.startsWith("<") && type.endsWith(">"))
212:                 {
213:                         return AstFactory.newAQuoteType(new LexQuoteToken(type.substring(1, type.length() - 1), location));
214:•                } else if (type.startsWith(OPTIONAL_TYPE))
215:                 {
216:                         return AstFactory.newAOptionalType(location, convertGeneric(type).get(0));
217:                 } else
218:                 {
219:                         // String module = "";
220:                         String name = "";
221:•                        if (type.contains("::"))
222:                         {
223:                                 module = type.substring(0, type.indexOf(":"));
224:                                 name = type.substring(type.lastIndexOf(":") + 1);
225:                         } else
226:                         {
227:                                 name = type;
228:                         }
229:
230:                         LexNameToken typeName = new LexNameToken(module, name, location);
231:                         return AstFactory.newANamedInvariantType(typeName, null);
232:                 }
233:
234:         }
235:
236:         private PType convertBasicType(String type)
237:         {
238:                 String name = type.toLowerCase();
239:•                if (name.equals("bool"))
240:                 {
241:                         return AstFactory.newABooleanBasicType(location);
242:•                } else if (name.equals("char"))
243:                 {
244:                         return AstFactory.newACharBasicType(location);
245:•                } else if (name.equals("token"))
246:                 {
247:                         return AstFactory.newATokenBasicType(location);
248:•                } else if (name.equals("int"))
249:                 {
250:                         return AstFactory.newAIntNumericBasicType(location);
251:•                } else if (name.equals("nat"))
252:                 {
253:                         return AstFactory.newANatNumericBasicType(location);
254:•                } else if (name.equals("nat1"))
255:                 {
256:                         return AstFactory.newANatOneNumericBasicType(location);
257:•                } else if (name.equals("rat"))
258:                 {
259:                         return AstFactory.newARationalNumericBasicType(location);
260:•                } else if (name.equals("real"))
261:                 {
262:                         return AstFactory.newARealNumericBasicType(location);
263:                 }
264:                 return null;
265:         }
266:
267:         /**
268:          * The name must start with < and end with > and be separated by comma.
269:          *
270:          * @param name
271:          * @return
272:          */
273:         private PTypeList convertGeneric(String name)
274:         {
275:                 String nameNoLessOrGreater = name.substring(name.indexOf("<") + 1, name.length() - 1);
276:
277:                 String[] typeStrings = nameNoLessOrGreater.split(",");
278:
279:                 // decide if the split is valid or if the type is a single generic type
280:                 boolean notSingleGenericType = true;
281:•                for (String part : typeStrings)
282:                 {
283:•                        if (part.replaceAll("[^<]", "").length() != part.replaceAll("[^>]", "").length())
284:                         {
285:                                 notSingleGenericType = false;
286:                         }
287:                 }
288:
289:                 PTypeList types = new PTypeList();
290:•                if (notSingleGenericType)
291:                 {
292:•                        for (String t : typeStrings)
293:                         {
294:                                 types.add(convert(t, null));
295:                         }
296:                 } else
297:                 {
298:                         types.add(convert(nameNoLessOrGreater, null));
299:                 }
300:                 return types;
301:         }
302:
303:         public PType createRecord(Class innerType)
304:         {
305:
306:                 List<AFieldField> fields = new Vector<AFieldField>();
307:
308:•                for (Property p : innerType.getOwnedAttributes())
309:                 {
310:                         LexNameToken tagname = new LexNameToken("", p.getName(), location);
311:                         String tag = p.getName();
312:                         PType type = convert(p.getType());
313:                         fields.add(AstFactory.newAFieldField(tagname, tag, type, false));
314:                 }
315:
316:                 return AstFactory.newARecordInvariantType(location, fields);
317:         }
318:
319:         public PType createEnumeration(Enumeration elem)
320:         {
321:                 PTypeList types = new PTypeList();
322:•                for (EnumerationLiteral lit : elem.getOwnedLiterals())
323:                 {
324:•                        if (lit.getName().startsWith("<") && lit.getName().endsWith(">"))
325:                         {
326:                                 types.add(convert(lit.getName(), null));
327:                         } else
328:                         {
329:                                 System.out.println("Problem with conversion of enumeration: "
330:                                                 + elem.getName());
331:                         }
332:
333:                 }
334:
335:                 return AstFactory.newAUnionType(location, types);
336:         }
337: }