Skip to content

Package: SuperGenerationTransformer$2

SuperGenerationTransformer$2

nameinstructionbranchcomplexitylinemethod
handle(ConstructorByReferenceState)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
handle(ConstructorByTypeAndSignatureState)
M: 12 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
handle(ConstructorInvalidState)
M: 12 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
{...}
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: package de.fhdw.wtf.generator.transformer.transformers.classTransformer;
2:
3: import java.util.Collection;
4: import java.util.HashMap;
5: import java.util.Iterator;
6: import java.util.LinkedList;
7: import java.util.List;
8: import java.util.Map;
9: import java.util.Vector;
10:
11: import de.fhdw.wtf.common.ast.Attribute;
12: import de.fhdw.wtf.common.ast.Constructor;
13: import de.fhdw.wtf.common.ast.ConstructorByReferenceState;
14: import de.fhdw.wtf.common.ast.ConstructorByTypeAndSignatureState;
15: import de.fhdw.wtf.common.ast.ConstructorInvalidState;
16: import de.fhdw.wtf.common.ast.ConstructorOrOperation;
17: import de.fhdw.wtf.common.ast.ConstructorReference;
18: import de.fhdw.wtf.common.ast.Group;
19: import de.fhdw.wtf.common.ast.Model;
20: import de.fhdw.wtf.common.ast.type.AtomicType;
21: import de.fhdw.wtf.common.ast.type.BaseType;
22: import de.fhdw.wtf.common.ast.type.ClassType;
23: import de.fhdw.wtf.common.ast.type.CompositeType;
24: import de.fhdw.wtf.common.ast.type.ProductElementType;
25: import de.fhdw.wtf.common.ast.type.ProductType;
26: import de.fhdw.wtf.common.ast.type.Type;
27: import de.fhdw.wtf.common.ast.type.TypeProxy;
28: import de.fhdw.wtf.common.ast.visitor.AtomicTypeVisitorReturnException;
29: import de.fhdw.wtf.common.ast.visitor.ConstructorReferenceStateVisitorReturnException;
30: import de.fhdw.wtf.common.ast.visitor.TypeVisitorReturnException;
31: import de.fhdw.wtf.common.exception.walker.TaskException;
32: import de.fhdw.wtf.common.task.TaskExecutor;
33: import de.fhdw.wtf.common.token.DummyToken;
34: import de.fhdw.wtf.generator.java.generatorModel.GenAnyType;
35: import de.fhdw.wtf.generator.java.generatorModel.GenAttributeModifier;
36: import de.fhdw.wtf.generator.java.generatorModel.GenClass;
37: import de.fhdw.wtf.generator.java.generatorModel.GenClassClass;
38: import de.fhdw.wtf.generator.java.generatorModel.GenClassModifier;
39: import de.fhdw.wtf.generator.java.generatorModel.GenComment;
40: import de.fhdw.wtf.generator.java.generatorModel.GenException;
41: import de.fhdw.wtf.generator.java.generatorModel.GenExternalInterfaceClass;
42: import de.fhdw.wtf.generator.java.generatorModel.GenFullParsedOperationState;
43: import de.fhdw.wtf.generator.java.generatorModel.GenHasNoGenericType;
44: import de.fhdw.wtf.generator.java.generatorModel.GenInterfaceClass;
45: import de.fhdw.wtf.generator.java.generatorModel.GenInterfaceWithClassImplClass;
46: import de.fhdw.wtf.generator.java.generatorModel.GenJavaAttribute;
47: import de.fhdw.wtf.generator.java.generatorModel.GenJavaOperation;
48: import de.fhdw.wtf.generator.java.generatorModel.GenMutableMap;
49: import de.fhdw.wtf.generator.java.generatorModel.GenOperationModifier;
50: import de.fhdw.wtf.generator.java.generatorModel.GenParameter;
51: import de.fhdw.wtf.generator.java.generatorModel.GenPrimitiveClass;
52: import de.fhdw.wtf.generator.java.generatorModel.GenSimpleInterfaceClass;
53: import de.fhdw.wtf.generator.java.generatorModel.GenStringType;
54: import de.fhdw.wtf.generator.java.generatorModel.GenType;
55: import de.fhdw.wtf.generator.java.generatorModel.GenTypeReferenceByName;
56: import de.fhdw.wtf.generator.java.generatorModel.GenTypeReferenceByReference;
57: import de.fhdw.wtf.generator.java.generatorModel.GenUnqualifiedPackage;
58: import de.fhdw.wtf.generator.java.generatorModel.GenUserClass;
59: import de.fhdw.wtf.generator.java.generatorModel.GenVisibility;
60: import de.fhdw.wtf.generator.java.generatorModel.GenVoidType;
61: import de.fhdw.wtf.generator.java.generatorModel.GeneratorModel;
62: import de.fhdw.wtf.generator.java.generatorModel.Generic;
63: import de.fhdw.wtf.generator.java.visitor.GenClassVisitorException;
64: import de.fhdw.wtf.generator.java.visitor.GenInterfaceClassVisitorException;
65: import de.fhdw.wtf.generator.transformer.exception.GenTypeNotReferencedException;
66: import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
67:
68: /**
69: * This Task generates the $super-methods and methods that are being called within $super (such as the getter for the
70: * tuples) in every class. The $super-methods main purpose is to call the right constructors of super classes in the
71: * right order.
72: */
73: public class SuperGenerationTransformer extends SimpleWalkerTask {
74:         
75:         /**
76:          * The generator model to add constructor calls to.
77:          */
78:         private final GeneratorModel generatorModel;
79:         
80:         /**
81:          * Contains the information which type is responsible to instantiate which other types.
82:          */
83:         private final Map<Type, List<Type>> callOrder;
84:         
85:         /**
86:          * This map contains the numbers of generic tuples to generate for the getter-Methods for super constructor
87:          * parameters. The number stands for the amount of generic fields in the tuple.
88:          */
89:         private final Map<Integer, GenUserClass> genericTuplesToGenerate;
90:         
91:         /**
92:          * Constructor of {@link SuperGenerationTransformer}.
93:          *
94:          * @param m
95:          * The model to traverse.
96:          * @param taskmanager
97:          * The task manager to register with.
98:          * @param generatorModel
99:          * the model, which will be checked.
100:          */
101:         public SuperGenerationTransformer(final Model m, final TaskExecutor taskmanager, final GeneratorModel generatorModel) {
102:                 super(m, taskmanager);
103:                 this.callOrder = m.getConstructorCallDependencies();
104:                 this.generatorModel = generatorModel;
105:                 this.genericTuplesToGenerate = new HashMap<>();
106:         }
107:         
108:         @Override
109:         public void handleClass(final ClassType c) throws TaskException {
110:                 final GenClass genClass = this.generatorModel.getClassMapping().get(c);
111:                 genClass.accept(new GenClassVisitorException<TaskException>() {
112:                         
113:                         @Override
114:                         public void handle(final GenClassClass classClass) throws TaskException {
115:                                 // ConstructorCallGenerationTask.this.handleGenClassClass(c, classClass);
116:                         }
117:                         
118:                         @Override
119:                         public void handle(final GenInterfaceClass interfaceClass) throws TaskException {
120:                                 interfaceClass.accept(new GenInterfaceClassVisitorException<TaskException>() {
121:                                         
122:                                         @Override
123:                                         public void handle(final GenSimpleInterfaceClass simpleInterface) throws TaskException {
124:                                                 // Nothing to do.
125:                                         }
126:                                         
127:                                         @Override
128:                                         public void handle(final GenInterfaceWithClassImplClass interfaceWithImplClass)
129:                                                         throws TaskException {
130:                                                 SuperGenerationTransformer.this.handleGenInterfaceWithClassImplClass(c, interfaceWithImplClass);
131:                                         }
132:                                         
133:                                         @Override
134:                                         public void handle(final GenExternalInterfaceClass iface) throws TaskException {
135:                                                 // Nothing to do.
136:                                         }
137:                                         
138:                                 });
139:                         }
140:                         
141:                         @Override
142:                         public void handle(final GenPrimitiveClass primitiveClass) {
143:                                 // Nothing to do.
144:                         }
145:                         
146:                 });
147:         }
148:         
149:         /**
150:          * Generates the constructors and the corresponding $super and $setThis methods for the classType c and its
151:          * GenInterfaceWithClassImplClass.
152:          *
153:          * @param c
154:          * the ClassType.
155:          * @param interfaceClass
156:          * The interface class for c.
157:          * @throws TaskException
158:          * if the types don't match each other.
159:          */
160:         private void handleGenInterfaceWithClassImplClass(final ClassType c,
161:                         final GenInterfaceWithClassImplClass interfaceClass) throws TaskException {
162:                 final GenClassClass genClassClass = interfaceClass.getClassRepresentation();
163:                 final List<Type> typesToInstantiate =
164:                                 this.callOrder.containsKey(c) ? this.callOrder.get(c) : new LinkedList<Type>();
165:                 int superMethodNumber = 0;
166:                 final Collection<Constructor> constructors = c.getConstructors();
167:                 final Iterator<Constructor> constructorIterator = constructors.iterator();
168:                 while (constructorIterator.hasNext()) {
169:                         superMethodNumber++;
170:                         final Constructor constructor = constructorIterator.next();
171:                         this.generateConstructorAndSuper(
172:                                         genClassClass,
173:                                         interfaceClass,
174:                                         constructor.getParameters(),
175:                                         constructor.getSuperConstructors(),
176:                                         typesToInstantiate,
177:                                         superMethodNumber);
178:                 }
179:                 this.generate$setThis(genClassClass, interfaceClass, typesToInstantiate);
180:         }
181:         
182:         /**
183:          * generates the $setThis-Method.
184:          *
185:          * @param genClassClass
186:          * the GenClassClass.
187:          * @param interfaceClass
188:          * the InterfaceClass for genClassClass.
189:          * @param typesToInstantiate
190:          * the types that have to be instantiated.
191:          * @throws GenTypeNotReferencedException
192:          * if no GenType for a super type can be found.
193:          */
194:         private void generate$setThis(final GenClassClass genClassClass,
195:                         final GenInterfaceWithClassImplClass interfaceClass,
196:                         final List<Type> typesToInstantiate) throws GenTypeNotReferencedException {
197:                 final StringBuilder $setThisMethodBuilder = new StringBuilder("this.This=This;");
198:                 final Iterator<Type> superTypes = typesToInstantiate.iterator();
199:                 while (superTypes.hasNext()) {
200:                         final Type superType = superTypes.next();
201:                         final GenType genType = this.generatorModel.getGenTypeForType(superType);
202:                         final String typeName = genType.getFullyQualifiedTypeName();
203:                         final String typeNameImpl = typeName + "$Impl";
204:                         final String typeNameImplShort = typeNameImpl.substring(typeNameImpl.lastIndexOf('.') + 1);
205:                         final String innerPackage = typeName + "_InnerPackage." + typeNameImplShort;
206:                         
207:                         $setThisMethodBuilder.append("\n\t\t");
208:                         $setThisMethodBuilder.append("((");
209:                         $setThisMethodBuilder.append(innerPackage);
210:                         $setThisMethodBuilder.append(")");
211:                         $setThisMethodBuilder.append("$generatedObjects.get(new de.fhdw.wtf.context.model.Str(\"");
212:                         $setThisMethodBuilder.append(innerPackage);
213:                         $setThisMethodBuilder.append("\"))).$setThis(this);");
214:                 }
215:                 
216:                 final List<GenParameter> $setThisParams = new Vector<>();
217:                 $setThisParams.add(GenParameter.create(
218:                                 "This",
219:                                 GenTypeReferenceByName.create(interfaceClass.getFullyQualifiedTypeName())));
220:                 final GenJavaOperation $setThisOperation =
221:                                 GenJavaOperation.create("$setThis", $setThisParams, GenFullParsedOperationState.create(
222:                                                 GenComment.create("/**\n\t * Sets This.\n\t **/"),
223:                                                 new Vector<GenException>(),
224:                                                 GenTypeReferenceByName.create(GenVoidType.getInstance().getFullyQualifiedTypeName()),
225:                                                 new Vector<GenOperationModifier>(),
226:                                                 GenVisibility.PUBLIC,
227:                                                 $setThisMethodBuilder.toString()));
228:                 genClassClass.addOperation($setThisOperation);
229:         }
230:         
231:         /**
232:          * Generates a constructor for genClassClass.
233:          *
234:          * @param genClassClass
235:          * the GenClassClass.
236:          * @param interfaceClass
237:          * the InterfaceClass for genClassClass.
238:          * @param parameters
239:          * the parameters of the constructor to create.
240:          * @param superConstructors
241:          * the super constructors to call.
242:          * @param typesToInstantiate
243:          * the types that have to be instantiated.
244:          * @param superMethodNumber
245:          * the number of the currently generated $super-method
246:          * @throws TaskException
247:          * if the types don't match each other.
248:          */
249:         private void generateConstructorAndSuper(final GenClassClass genClassClass,
250:                         final GenInterfaceClass interfaceClass,
251:                         final ProductType parameters,
252:                         final Collection<ConstructorReference> superConstructors,
253:                         final List<Type> typesToInstantiate,
254:                         final int superMethodNumber) throws TaskException {
255:                 final GenParameter generatedObjects =
256:                                 GenParameter.create(
257:                                                 "$generatedObjects",
258:                                                 GenMutableMap.create(GenStringType.getInstance(), GenAnyType.getInstance()));
259:                 final List<GenParameter> genParameters = this.createGenParameters(parameters);
260:                 final List<GenParameter> genParametersWithMap = new LinkedList<>();
261:                 genParametersWithMap.add(generatedObjects);
262:                 genParametersWithMap.addAll(genParameters);
263:                 final String prefix = genParameters.isEmpty() ? "" : ", ";
264:                 this.generateConstructor(
265:                                 genClassClass,
266:                                 genParameters,
267:                                 "this("
268:                                                 + "new de.fhdw.wtf.context.model.collections.MutableMap<de.fhdw.wtf.context.model.Str,de.fhdw.wtf.context.model.AnyType>()"
269:                                                 + this.generateParameterString(prefix, genParameters) + ";",
270:                                 GenVisibility.PUBLIC);
271:                 this.generateConstructor(
272:                                 genClassClass,
273:                                 genParametersWithMap,
274:                                 this.generateSuperCall(genParametersWithMap, genParameters),
275:                                 GenVisibility.PUBLIC);
276:                 this.generateSuper(
277:                                 genClassClass,
278:                                 interfaceClass,
279:                                 genParametersWithMap,
280:                                 genParameters,
281:                                 superConstructors,
282:                                 typesToInstantiate,
283:                                 superMethodNumber);
284:                 this.generateInitializeOnCreation(genClassClass, genParameters);
285:         }
286:         
287:         /**
288:          * Generates initializeOnCreation.
289:          *
290:          * @param genClassClass
291:          * for class.
292:          * @param genParameters
293:          * with parameters.
294:          */
295:         private void generateInitializeOnCreation(final GenClassClass genClassClass, final List<GenParameter> genParameters) {
296:                 // TODO In order to support final attributes this operation can be removed in the future. Before a
297:                 // non-generation-part like area has to be added to the constructor.
298:                 genClassClass.addOperation(GenJavaOperation.create(
299:                                 "$initializeOnCreation",
300:                                 genParameters,
301:                                 GenFullParsedOperationState.create(
302:                                                 GenComment.create("/**\n\t * Initializes the objects fields.\n\t */"),
303:                                                 new Vector<GenException>(),
304:                                                 GenTypeReferenceByName.create("void"),
305:                                                 new Vector<GenOperationModifier>(),
306:                                                 GenVisibility.PRIVATE,
307:                                                 "// TODO implement initializeOnCreation")));
308:                 
309:         }
310:         
311:         /**
312:          * Generates the $super-Method for a list of super constructors.
313:          *
314:          * @param genClassClass
315:          * the GenClassClass.
316:          * @param interfaceClass
317:          * the InterfaceClass for genClassClass.
318:          * @param genParametersWithMap
319:          * The parameters of $super.
320:          * @param genParametersWithoutMap
321:          * The parameters to pass to the tuple getters.
322:          * @param superConstructors
323:          * the super constructors to call.
324:          * @param typesToInstantiate
325:          * the types that have to be instantiated.
326:          * @param superMethodNumber
327:          * the number of the currently generated $super-method
328:          * @throws TaskException
329:          * if the types don't match each other.
330:          */
331:         private void generateSuper(final GenClassClass genClassClass,
332:                         final GenInterfaceClass interfaceClass,
333:                         final List<GenParameter> genParametersWithMap,
334:                         final List<GenParameter> genParametersWithoutMap,
335:                         final Collection<ConstructorReference> superConstructors,
336:                         final List<Type> typesToInstantiate,
337:                         final int superMethodNumber) throws TaskException {
338:                 final StringBuilder superMethodBuilder = new StringBuilder();
339:                 int superTypeNumber = 0;
340:                 final Iterator<Type> superTypes = typesToInstantiate.iterator();
341:                 while (superTypes.hasNext()) {
342:                         superTypeNumber++;
343:                         final Type superType = superTypes.next();
344:                         final GenType genType = this.generatorModel.getGenTypeForType(superType);
345:                         final Constructor constructorToCall = this.getConstructorForType(superType, superConstructors);
346:                         final List<GenParameter> constructorParametersWithoutMap =
347:                                         this.createGenParameters(constructorToCall.getParameters());
348:                         final String typeName = genType.getFullyQualifiedTypeName();
349:                         final String tupleName = "tuple_" + superMethodNumber + "_" + superTypeNumber;
350:                         final String typeNameImpl = typeName + "$Impl";
351:                         final String typeNameImplShort = typeNameImpl.substring(typeNameImpl.lastIndexOf('.') + 1);
352:                         final String innerPackage = typeName + "_InnerPackage." + typeNameImplShort;
353:                         superMethodBuilder.append("if ($generatedObjects.get(new de.fhdw.wtf.context.model.Str(\"");
354:                         superMethodBuilder.append(innerPackage);
355:                         superMethodBuilder.append("\"))==null){\n\t\t\t\t");
356:                         if (!constructorParametersWithoutMap.isEmpty()) {
357:                                 superMethodBuilder.append(this.generateTupleInstantiationStringAndTupleClassAndTupleGetter(
358:                                                 genClassClass,
359:                                                 tupleName,
360:                                                 typeName,
361:                                                 constructorParametersWithoutMap,
362:                                                 genParametersWithoutMap,
363:                                                 superMethodNumber,
364:                                                 superTypeNumber));
365:                                 superMethodBuilder.append("\n\t\t\t\t");
366:                         }
367:                         superMethodBuilder.append("this.$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
368:                         superMethodBuilder.append(innerPackage);
369:                         superMethodBuilder.append("\")");
370:                         superMethodBuilder.append(", ");
371:                         superMethodBuilder.append("new ");
372:                         superMethodBuilder.append(innerPackage);
373:                         superMethodBuilder.append("(");
374:                         superMethodBuilder.append("$generatedObjects");
375:                         if (!constructorParametersWithoutMap.isEmpty()) {
376:                                 superMethodBuilder.append(", ");
377:                                 superMethodBuilder.append(this
378:                                                 .generateTupleGetterCallString(tupleName, constructorParametersWithoutMap));
379:                         } else {
380:                                 superMethodBuilder.append(")");
381:                         }
382:                         superMethodBuilder.append(");");
383:                         superMethodBuilder.append("\n\t\t\t}\n\t\t");
384:                         superMethodBuilder.append("else{\n\t\t\t\t");
385:                         superMethodBuilder.append("this.$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
386:                         superMethodBuilder.append(innerPackage);
387:                         superMethodBuilder.append("\")");
388:                         superMethodBuilder.append(", ");
389:                         superMethodBuilder.append("$generatedObjects.get(new de.fhdw.wtf.context.model.Str(\"");
390:                         superMethodBuilder.append(innerPackage);
391:                         superMethodBuilder.append("\")));\n\t\t\t}\n\t\t");
392:                 }
393:                 superMethodBuilder.append("this.$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
394:                 superMethodBuilder.append(genClassClass.getFullyQualifiedTypeName());
395:                 superMethodBuilder.append("\"),this);");
396:                 superMethodBuilder.append("\n\t\t");
397:                 superMethodBuilder.append("$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
398:                 superMethodBuilder.append(genClassClass.getFullyQualifiedTypeName());
399:                 superMethodBuilder.append("\"),this);");
400:                 superMethodBuilder.append("\n\t\t");
401:                 superMethodBuilder.append("this.$setThis(this);");
402:                 
403:                 final GenJavaOperation superOperation =
404:                                 GenJavaOperation.create(
405:                                                 "$super",
406:                                                 GenVisibility.PRIVATE,
407:                                                 genParametersWithMap,
408:                                                 new LinkedList<GenException>(),
409:                                                 superMethodBuilder.toString(),
410:                                                 GenVoidType.getInstance(),
411:                                                 new LinkedList<GenOperationModifier>(),
412:                                                 GenComment.create("/**\n\t * Instantiates objects for the super types of this class.\n\t **/"));
413:                 genClassClass.addOperation(superOperation);
414:         }
415:         
416:         /**
417:          * Generates a tuple with the same amount of generic fields as the size of constructorParametersWithoutMap (if it
418:          * does not already exist), a matching getter method in genClassClass that returns a tuple instantiation filled with
419:          * values matching the types of constructorParametersWithoutMap and a call-string to that getter-method including a
420:          * tuple reference with the name tuple_superMethodNumber_superTypeNumber.
421:          *
422:          * @param genClassClass
423:          * the class to generate $super for.
424:          * @param tupleName
425:          * the name of the tuple reference to generate
426:          * @param superTypeName
427:          * the name of the super type for the todo of the getter.
428:          * @param constructorParametersWithoutMap
429:          * the parameters of the super type constructor without $generatedObjects.
430:          * @param genParametersWithoutMap
431:          * the parameters of $super without $generatedObjects.
432:          * @param superMethodNumber
433:          * the number of the super method.
434:          * @param superTypeNumber
435:          * the number of the super type.
436:          * @return a call-string to that getter-method including a tuple reference with the name
437:          * tuple_superMethodNumber_superTypeNumber.
438:          */
439:         private String generateTupleInstantiationStringAndTupleClassAndTupleGetter(final GenClassClass genClassClass,
440:                         final String tupleName,
441:                         final String superTypeName,
442:                         final List<GenParameter> constructorParametersWithoutMap,
443:                         final List<GenParameter> genParametersWithoutMap,
444:                         final int superMethodNumber,
445:                         final int superTypeNumber) {
446:                 final StringBuilder resultStringBuilder = new StringBuilder();
447:                 final StringBuilder genericListStringBuilder = new StringBuilder();
448:                 final Iterator<GenParameter> parameters = constructorParametersWithoutMap.iterator();
449:                 while (parameters.hasNext()) {
450:                         final GenParameter current = parameters.next();
451:                         genericListStringBuilder.append(current.getTyp().getFullyQualifiedNameWithGenericArguments());
452:                         if (parameters.hasNext()) {
453:                                 genericListStringBuilder.append(", ");
454:                         }
455:                 }
456:                 final int genericCount = constructorParametersWithoutMap.size();
457:                 final String superParameterString = this.generateParameterString("", genParametersWithoutMap);
458:                 final String genericString = "<" + genericListStringBuilder.toString() + "> ";
459:                 final String tupleTypePrefix = "generated.Tuple" + genericCount;
460:                 final String tupleTypeString = tupleTypePrefix + genericString;
461:                 final String getterName = "$getTuple_" + superMethodNumber + "_" + superTypeNumber;
462:                 resultStringBuilder.append(tupleTypeString);
463:                 resultStringBuilder.append(tupleName);
464:                 resultStringBuilder.append(" = ");
465:                 resultStringBuilder.append("this.");
466:                 resultStringBuilder.append(getterName);
467:                 resultStringBuilder.append("(");
468:                 resultStringBuilder.append(superParameterString);
469:                 resultStringBuilder.append(";");
470:                 final GenUserClass tuple = this.generateTupleClass(genericCount);
471:                 this.generateTupleGetterMethod(
472:                                 genClassClass,
473:                                 getterName,
474:                                 genParametersWithoutMap,
475:                                 constructorParametersWithoutMap,
476:                                 tupleTypeString,
477:                                 tupleTypePrefix,
478:                                 genericString,
479:                                 tuple,
480:                                 superTypeName);
481:                 return resultStringBuilder.toString();
482:         }
483:         
484:         /**
485:          * Generates a tuple class with name Tuple<genericCount> and genericCount generic fields if it does not exist
486:          * already.
487:          *
488:          * @param genericCount
489:          * the amount of generic types.
490:          * @return a tuple class with name Tuple<genericCount> and genericCount generic fields.
491:          */
492:         private GenUserClass generateTupleClass(final int genericCount) {
493:                 if (this.genericTuplesToGenerate.containsKey(genericCount)) {
494:                         return this.genericTuplesToGenerate.get(genericCount);
495:                 }
496:                 final List<Generic> generics = new Vector<>();
497:                 final List<GenJavaOperation> operations = new Vector<>();
498:                 final List<GenJavaAttribute> attributes = new Vector<>();
499:                 final List<GenParameter> constructorParameters = new Vector<>();
500:                 final StringBuilder constructorMethodBuilder = new StringBuilder();
501:                 for (int i = 1; i <= genericCount; i++) {
502:                         final String genericTypeName = "ValueType" + i;
503:                         final String genericAttributeNameSuffix = "alue" + i;
504:                         final String genericAttributeName = "v" + genericAttributeNameSuffix;
505:                         final String genericOperationNameSuffix = "V" + genericAttributeNameSuffix;
506:                         final Generic generic = Generic.create(genericTypeName, GenHasNoGenericType.create());
507:                         generics.add(generic);
508:                         final GenJavaOperation operation =
509:                                         GenJavaOperation.create(
510:                                                         "get" + genericOperationNameSuffix,
511:                                                         new Vector<GenParameter>(),
512:                                                         GenFullParsedOperationState.create(
513:                                                                         GenComment.create("/**\n\t * Returns the value of type " + genericTypeName
514:                                                                                         + ".\n\t **/"),
515:                                                                         new Vector<GenException>(),
516:                                                                         GenTypeReferenceByReference.create(generic),
517:                                                                         new Vector<GenOperationModifier>(),
518:                                                                         GenVisibility.PUBLIC,
519:                                                                         "return this." + genericAttributeName + ";"));
520:                         operations.add(operation);
521:                         final GenJavaAttribute attribute =
522:                                         GenJavaAttribute.create(
523:                                                         genericAttributeName,
524:                                                         GenVisibility.PRIVATE,
525:                                                         generic,
526:                                                         new Vector<GenAttributeModifier>());
527:                         attributes.add(attribute);
528:                         final GenParameter parameter = GenParameter.create(genericAttributeName, generic);
529:                         constructorParameters.add(parameter);
530:                         constructorMethodBuilder.append("this." + genericAttributeName + " = " + genericAttributeName + ";");
531:                         if (i < genericCount) {
532:                                 constructorMethodBuilder.append("\n\t\t");
533:                         }
534:                 }
535:                 
536:                 final GenUserClass tuple =
537:                                 GenUserClass.create(
538:                                                 "Tuple" + genericCount,
539:                                                 operations,
540:                                                 new Vector<GenInterfaceClass>(),
541:                                                 attributes,
542:                                                 new Vector<GenClassModifier>(),
543:                                                 new Vector<GenJavaOperation>(),
544:                                                 null,
545:                                                 GenUnqualifiedPackage.create("generated"),
546:                                                 GenComment.create("/**\n* A tuple with " + genericCount + " generic fields.\n**/"),
547:                                                 "");
548:                 
549:                 tuple.getGenerics().addAll(generics);
550:                 
551:                 final GenJavaOperation constructor =
552:                                 GenJavaOperation.create(
553:                                                 "",
554:                                                 constructorParameters,
555:                                                 GenFullParsedOperationState.create(
556:                                                                 GenComment.create("/**\n\t * Creates a new Tuple" + genericCount + ".\n\t **/"),
557:                                                                 new Vector<GenException>(),
558:                                                                 GenTypeReferenceByReference.create(tuple),
559:                                                                 new Vector<GenOperationModifier>(),
560:                                                                 GenVisibility.PUBLIC,
561:                                                                 constructorMethodBuilder.toString()));
562:                 tuple.getConstructors().add(constructor);
563:                 
564:                 this.generatorModel.addNonAstClass(tuple);
565:                 this.genericTuplesToGenerate.put(genericCount, tuple);
566:                 return tuple;
567:         }
568:         
569:         /**
570:          * Generates the getter method for the tuple of a concrete super constructor call. The generated method enables the
571:          * user to provide the parameters for the super constructor call in a tuple.
572:          *
573:          * @param genClassClass
574:          * the class with $super.
575:          * @param getterName
576:          * the name of the getter.
577:          * @param genParametersWithoutMap
578:          * the parameters of $super without $generatedObjects.
579:          * @param constructorParametersWithoutMap
580:          * the parameters of the super constructor without $generatedObjects.
581:          * @param tupleTypeString
582:          * the concrete type of the tuple as string.
583:          * @param tupleTypePrefix
584:          * the name of the tuple type as string.
585:          * @param genericString
586:          * the string with the generic types of the tuple.
587:          * @param returnType
588:          * the return type of the getter (the tuple itself).
589:          * @param superTypeName
590:          * the name of the super type for the todo comment.
591:          */
592:         private void generateTupleGetterMethod(final GenClassClass genClassClass,
593:                         final String getterName,
594:                         final List<GenParameter> genParametersWithoutMap,
595:                         final List<GenParameter> constructorParametersWithoutMap,
596:                         final String tupleTypeString,
597:                         final String tupleTypePrefix,
598:                         final String genericString,
599:                         final GenType returnType,
600:                         final String superTypeName) {
601:                 final StringBuilder methodStringBuilder =
602:                                 new StringBuilder(
603:                                                 "//TODO replace the following null values with your desired values for the constructor of the super type "
604:                                                                 + superTypeName);
605:                 methodStringBuilder.append("\n\t\t");
606:                 methodStringBuilder.append(tupleTypeString);
607:                 methodStringBuilder.append(" tuple ");
608:                 methodStringBuilder.append("= new ");
609:                 methodStringBuilder.append(tupleTypePrefix);
610:                 methodStringBuilder.append("<>(" + this.generateNullStringWithCasts(constructorParametersWithoutMap) + ");");
611:                 methodStringBuilder.append("\n\t\treturn tuple;");
612:                 
613:                 final GenJavaOperation tupleGetterMethod =
614:                                 GenJavaOperation.create(
615:                                                 genericString + " " + getterName,
616:                                                 genParametersWithoutMap,
617:                                                 GenFullParsedOperationState.create(
618:                                                                 GenComment.create("/**\n\t * Returns a tuple with the parameters for a "
619:                                                                                 + "super constructor." + "\n\t * "
620:                                                                                 + "The name of this operation describes the signature of "
621:                                                                                 + "said constructor." + "\n\t **/"),
622:                                                                 new Vector<GenException>(),
623:                                                                 GenTypeReferenceByReference.create(returnType),
624:                                                                 new Vector<GenOperationModifier>(),
625:                                                                 GenVisibility.PRIVATE,
626:                                                                 methodStringBuilder.toString()));
627:                 genClassClass.addOperation(tupleGetterMethod);
628:                 
629:         }
630:         
631:         /**
632:          * Generates a comma separated parameter string starting with '(' and ending with ')' with as many null values as
633:          * constructorParametersWithoutMap has entries. Adds a cast to the matching parameter type from
634:          * constructorParametersWithoutMap before each null value.
635:          *
636:          * @param constructorParametersWithoutMap
637:          * the parameters to use.
638:          * @return a comma separated parameter string starting with '(' and ending with ')' with as many null values as
639:          * constructorParametersWithoutMap has entries.
640:          */
641:         private String generateNullStringWithCasts(final List<GenParameter> constructorParametersWithoutMap) {
642:                 final StringBuilder resultBuilder = new StringBuilder();
643:                 final Iterator<GenParameter> parameters = constructorParametersWithoutMap.iterator();
644:                 while (parameters.hasNext()) {
645:                         resultBuilder.append("(");
646:                         resultBuilder.append(parameters.next().getTyp().getFullyQualifiedNameWithGenericArguments());
647:                         resultBuilder.append(") null");
648:                         if (parameters.hasNext()) {
649:                                 resultBuilder.append(",");
650:                         }
651:                 }
652:                 return resultBuilder.toString();
653:         }
654:         
655:         /**
656:          * Searches for a constructor in superConstructors that matches superType.
657:          *
658:          * @param superType
659:          * the superType.
660:          * @param superConstructors
661:          * a list of super constructors to call.
662:          * @return the matching constructor.
663:          * @throws TaskException
664:          * is being thrown when no matching constructor can be found in superConstructors.
665:          */
666:         private Constructor getConstructorForType(final Type superType,
667:                         final Collection<ConstructorReference> superConstructors) throws TaskException {
668:                 if (superConstructors.isEmpty()) {
669:                         return Constructor.create(
670:                                         ProductType.create(DummyToken.getInstance()),
671:                                         this.getTypeAsClassType(superType),
672:                                         new LinkedList<ConstructorReference>(),
673:                                         DummyToken.getInstance(),
674:                                         DummyToken.getInstance());
675:                 }
676:                 final Iterator<ConstructorReference> constructorReferences = superConstructors.iterator();
677:                 boolean found = false;
678:                 Constructor constructor = null;
679:                 while (!found && constructorReferences.hasNext()) {
680:                         constructor = this.getConstructorFromConstructorReference(constructorReferences.next());
681:                         found = constructor.getReturnType().equals(superType);
682:                 }
683:                 if (!found) {
684:                         throw new TaskException(
685:                                         "ConstructorCallGenerationTask: No constructor found while trying to generate code snipped for: "
686:                                                         + superType + " in $super!");
687:                 }
688:                 return constructor;
689:         }
690:         
691:         /**
692:          * Tries to find a ClassType for superType.
693:          *
694:          * @param superType
695:          * the type.
696:          * @return a ClassType that is representative for superType.
697:          * @throws TaskException
698:          * if no ClassType for the super type can be found.
699:          */
700:         private ClassType getTypeAsClassType(final Type superType) throws TaskException {
701:                 return superType.accept(new ClassTypeFinder());
702:         }
703:         
704:         /**
705:          * Tries to find a ClassType for superType.
706:          */
707:         private static class ClassTypeFinder implements TypeVisitorReturnException<ClassType, TaskException> {
708:                 
709:                 @Override
710:                 public ClassType handle(final AtomicType atomicType) throws TaskException {
711:                         return atomicType.accept(new AtomicTypeVisitorReturnException<ClassType, TaskException>() {
712:                                 
713:                                 @Override
714:                                 public ClassType handle(final BaseType baseType) throws TaskException {
715:                                         throw new TaskException("ConstructorCallGenerationTask: No BaseType allowed here!");
716:                                 }
717:                                 
718:                                 @Override
719:                                 public ClassType handle(final ClassType clazz) throws TaskException {
720:                                         return clazz;
721:                                 }
722:                                 
723:                         });
724:                 }
725:                 
726:                 @Override
727:                 public ClassType handle(final CompositeType compositeType) throws TaskException {
728:                         throw new TaskException("ConstructorCallGenerationTask: No SumType allowed here!");
729:                 }
730:                 
731:                 @Override
732:                 public ClassType handle(final TypeProxy typeProxy) throws TaskException {
733:                         return typeProxy.getTarget().accept(this);
734:                 }
735:                 
736:         }
737:         
738:         /**
739:          * Gets the constructor for reference.
740:          *
741:          * @param reference
742:          * the reference.
743:          * @return a constructor that is referenced via reference.
744:          * @throws TaskException
745:          * if no constructor can be found (Wrong reference state).
746:          */
747:         private Constructor getConstructorFromConstructorReference(final ConstructorReference reference)
748:                         throws TaskException {
749:                 /**
750:                  * Message if reference is in wrong state.
751:                  */
752:                 final String exceptionMessage =
753:                                 "ConstructorCallGenerationTask: ConstructorReference"
754:                                                 + " needs to be in ConstructorByReferenceState at this point. Current state: ";
755:                 
756:                 return reference.getState().accept(
757:                                 new ConstructorReferenceStateVisitorReturnException<Constructor, TaskException>() {
758:                                         
759:                                         @Override
760:                                         public Constructor handle(final ConstructorByTypeAndSignatureState byName) throws TaskException {
761:                                                 throw new TaskException(exceptionMessage + byName);
762:                                         }
763:                                         
764:                                         @Override
765:                                         public Constructor handle(final ConstructorInvalidState invalid) throws TaskException {
766:                                                 throw new TaskException(exceptionMessage + invalid);
767:                                         }
768:                                         
769:                                         @Override
770:                                         public Constructor handle(final ConstructorByReferenceState byReference) {
771:                                                 return byReference.getTarget();
772:                                         }
773:                                         
774:                                 });
775:         }
776:         
777:         /**
778:          * Creates GenParameters for parameters.
779:          *
780:          * @param parameters
781:          * the parameters to generate.
782:          * @return GenParameters that match parameters.
783:          * @throws GenTypeNotReferencedException
784:          * if no genType for a parameter type can be found.
785:          */
786:         private List<GenParameter> createGenParameters(final ProductType parameters) throws GenTypeNotReferencedException {
787:                 final List<ProductElementType> elements = parameters.getElements();
788:                 final List<GenParameter> result = new LinkedList<>();
789:                 for (final ProductElementType productElement : elements) {
790:                         final GenType paramType = this.generatorModel.getGenTypeForType(productElement.getType());
791:                         result.add(GenParameter.create(productElement.getName(), paramType));
792:                 }
793:                 return result;
794:         }
795:         
796:         /**
797:          * D Generates a constructor.
798:          *
799:          * @param genClassClass
800:          * for class.
801:          * @param genParameters
802:          * with parameters.
803:          * @param methodBody
804:          * with implementation.
805:          * @param visibility
806:          * visibility.
807:          */
808:         private void generateConstructor(final GenClassClass genClassClass,
809:                         final List<GenParameter> genParameters,
810:                         final String methodBody,
811:                         final GenVisibility visibility) {
812:                 final GenComment comment =
813:                                 GenComment
814:                                                 .create("/** \n\t * " + "Creates an instance of type " + genClassClass.getName() + "\n\t **/");
815:                 final GenJavaOperation constructorWithMap =
816:                                 GenJavaOperation.create(
817:                                                 "",
818:                                                 visibility,
819:                                                 genParameters,
820:                                                 new Vector<GenException>(),
821:                                                 methodBody,
822:                                                 genClassClass,
823:                                                 new Vector<GenOperationModifier>(),
824:                                                 comment);
825:                 genClassClass.addConstructor(constructorWithMap);
826:         }
827:         
828:         /**
829:          * Generates a call to a $super-Method with genParameters.
830:          *
831:          * @param genParametersWithMap
832:          * will be added (as names) to the call.
833:          * @param genParameters
834:          * parameters.
835:          * @return a $super-call.
836:          */
837:         private String generateSuperCall(final List<GenParameter> genParametersWithMap,
838:                         final List<GenParameter> genParameters) {
839:                 return "this.$super(" + this.generateParameterString("", genParametersWithMap) + ";"
840:                                 + "\n\t\tthis.$initializeOnCreation(" + this.generateParameterString("", genParameters) + ";";
841:         }
842:         
843:         /**
844:          * Generates a String with the names of the parameters (comma separated and with a ')' at the end).
845:          *
846:          * @param prefix
847:          * THe Prefix to add to the list.
848:          *
849:          * @param genParameters
850:          * parameters to include.
851:          * @return the parameter-string.
852:          */
853:         private String generateParameterString(final String prefix, final List<GenParameter> genParameters) {
854:                 final StringBuilder superCall = new StringBuilder(prefix);
855:                 final Iterator<GenParameter> parameterIterator = genParameters.iterator();
856:                 while (parameterIterator.hasNext()) {
857:                         final GenParameter parameter = parameterIterator.next();
858:                         superCall.append(parameter.getName());
859:                         if (parameterIterator.hasNext()) {
860:                                 superCall.append(", ");
861:                         }
862:                 }
863:                 superCall.append(")");
864:                 return superCall.toString();
865:         }
866:         
867:         /**
868:          * Generates a string to call a tuple getter.
869:          *
870:          * @param tupleName
871:          * name of the tuple.
872:          * @param constructorParametersWithoutMap
873:          * constructor parameters without $generatedObjects.
874:          * @return a string to call the tuple getter.
875:          */
876:         private String generateTupleGetterCallString(final String tupleName,
877:                         final List<GenParameter> constructorParametersWithoutMap) {
878:                 final StringBuilder call = new StringBuilder();
879:                 int genericFieldCount = 0;
880:                 final Iterator<GenParameter> parameters = constructorParametersWithoutMap.iterator();
881:                 while (parameters.hasNext()) {
882:                         genericFieldCount++;
883:                         final GenParameter current = parameters.next();
884:                         call.append(tupleName);
885:                         call.append(".<");
886:                         call.append(current.getTyp().getFullyQualifiedNameWithGenericArguments());
887:                         call.append(">getValue");
888:                         call.append(genericFieldCount);
889:                         call.append("(");
890:                         call.append(")");
891:                         if (parameters.hasNext()) {
892:                                 call.append(", ");
893:                         }
894:                 }
895:                 call.append(")");
896:                 return call.toString();
897:         }
898:         
899:         @Override
900:         public void handleGroup(final Group g) throws TaskException {
901:                 // Nothing to do.
902:                 
903:         }
904:         
905:         @Override
906:         public void handleAttribute(final Attribute a, final ClassType owner) throws TaskException {
907:                 // Nothing to do.
908:         }
909:         
910:         @Override
911:         public void handleConstructorOrOperation(final ConstructorOrOperation coo, final ClassType owner)
912:                         throws TaskException {
913:                 // Nothing to do.
914:         }
915:         
916:         @Override
917:         public void finalizeTask() throws TaskException {
918:                 // Nothing to do.
919:         }
920:         
921:         @Override
922:         public void beginTask() throws TaskException {
923:                 // Nothing to do.
924:         }
925:         
926: }