Skip to content

Method: handle(GenClassClass)

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