Skip to content

Package: ConstructorCallGenerationTask$1

ConstructorCallGenerationTask$1

nameinstructionbranchcomplexitylinemethod
handle(GenClassClass)
M: 0 C: 1
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
handle(GenInterfaceClass)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
handle(GenPrimitiveClass)
M: 1 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: 9
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 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, genParameters),
279:                                 GenVisibility.PUBLIC);
280:                 this.generateSuper(
281:                                 genClassClass,
282:                                 interfaceClass,
283:                                 genParametersWithMap,
284:                                 genParameters,
285:                                 superConstructors,
286:                                 typesToInstantiate,
287:                                 superMethodNumber);
288:                 this.generateInitializeOnCreation(genClassClass, genParameters);
289:         }
290:         
291:         private void generateInitializeOnCreation(final GenClassClass genClassClass, final List<GenParameter> genParameters) {
292:                 genClassClass.addOperation(GenJavaOperation.create(
293:                                 "initializeOnCreation",
294:                                 genParameters,
295:                                 GenFullParsedOperationState.create(
296:                                                 GenComment.create("/**\n\t * Initializes the objects fields.\n\t */"),
297:                                                 new Vector<GenException>(),
298:                                                 GenTypeReferenceByName.create("void"),
299:                                                 new Vector<GenOperationModifier>(),
300:                                                 GenVisibility.PRIVATE,
301:                                                 "// TODO implement initializeOnCreation")));
302:                 
303:         }
304:         
305:         /**
306:          * Generates the $super-Method for a list of super constructors.
307:          *
308:          * @param genClassClass
309:          * the GenClassClass.
310:          * @param interfaceClass
311:          * the InterfaceClass for genClassClass.
312:          * @param genParametersWithMap
313:          * The parameters of $super.
314:          * @param genParametersWithoutMap
315:          * The parameters to pass to the tuple getters.
316:          * @param superConstructors
317:          * the super constructors to call.
318:          * @param typesToInstantiate
319:          * the types that have to be instantiated.
320:          * @param superMethodNumber
321:          * the number of the currently generated $super-method
322:          * @throws TaskException
323:          * if the types don't match each other.
324:          */
325:         private void generateSuper(final GenClassClass genClassClass,
326:                         final GenInterfaceClass interfaceClass,
327:                         final List<GenParameter> genParametersWithMap,
328:                         final List<GenParameter> genParametersWithoutMap,
329:                         final Collection<ConstructorReference> superConstructors,
330:                         final List<Type> typesToInstantiate,
331:                         final int superMethodNumber) throws TaskException {
332:                 final StringBuilder superMethodBuilder = new StringBuilder();
333:                 int superTypeNumber = 0;
334:                 final Iterator<Type> superTypes = typesToInstantiate.iterator();
335:                 while (superTypes.hasNext()) {
336:                         superTypeNumber++;
337:                         final Type superType = superTypes.next();
338:                         final GenType genType = this.generatorModel.getGenTypeForType(superType);
339:                         final Constructor constructorToCall = this.getConstructorForType(superType, superConstructors);
340:                         final List<GenParameter> constructorParametersWithoutMap =
341:                                         this.createGenParameters(constructorToCall.getParameters());
342:                         final String typeName = genType.getFullyQualifiedTypeName();
343:                         final String tupleName = "tuple_" + superMethodNumber + "_" + superTypeNumber;
344:                         final String typeNameImpl = typeName + "$Impl";
345:                         final String typeNameImplShort = typeNameImpl.substring(typeNameImpl.lastIndexOf('.') + 1);
346:                         final String innerPackage = typeName + "_InnerPackage." + typeNameImplShort;
347:                         superMethodBuilder.append("if ($generatedObjects.get(new de.fhdw.wtf.context.model.Str(\"");
348:                         superMethodBuilder.append(innerPackage);
349:                         superMethodBuilder.append("\"))==null){\n\t\t\t\t");
350:                         if (!constructorParametersWithoutMap.isEmpty()) {
351:                                 superMethodBuilder.append(this.generateTupleInstantiationStringAndTupleClassAndTupleGetter(
352:                                                 genClassClass,
353:                                                 tupleName,
354:                                                 typeName,
355:                                                 constructorParametersWithoutMap,
356:                                                 genParametersWithoutMap,
357:                                                 superMethodNumber,
358:                                                 superTypeNumber));
359:                                 superMethodBuilder.append("\n\t\t\t\t");
360:                         }
361:                         superMethodBuilder.append("this.$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
362:                         superMethodBuilder.append(innerPackage);
363:                         superMethodBuilder.append("\")");
364:                         superMethodBuilder.append(", ");
365:                         superMethodBuilder.append("new ");
366:                         superMethodBuilder.append(innerPackage);
367:                         superMethodBuilder.append("(");
368:                         superMethodBuilder.append("$generatedObjects");
369:                         if (!constructorParametersWithoutMap.isEmpty()) {
370:                                 superMethodBuilder.append(", ");
371:                                 superMethodBuilder.append(this.generateTupleGetterAndCallString(
372:                                                 tupleName,
373:                                                 constructorParametersWithoutMap));
374:                         } else {
375:                                 superMethodBuilder.append(")");
376:                         }
377:                         superMethodBuilder.append(");");
378:                         superMethodBuilder.append("\n\t\t\t}\n\t\t");
379:                         superMethodBuilder.append("else{\n\t\t\t\t");
380:                         superMethodBuilder.append("this.$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
381:                         superMethodBuilder.append(innerPackage);
382:                         superMethodBuilder.append("\")");
383:                         superMethodBuilder.append(", ");
384:                         superMethodBuilder.append("$generatedObjects.get(new de.fhdw.wtf.context.model.Str(\"");
385:                         superMethodBuilder.append(innerPackage);
386:                         superMethodBuilder.append("\")));\n\t\t\t}\n\t\t");
387:                 }
388:                 superMethodBuilder.append("this.$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
389:                 superMethodBuilder.append(genClassClass.getFullyQualifiedTypeName());
390:                 superMethodBuilder.append("\"),this);");
391:                 superMethodBuilder.append("\n\t\t");
392:                 superMethodBuilder.append("$generatedObjects.put(new de.fhdw.wtf.context.model.Str(\"");
393:                 superMethodBuilder.append(genClassClass.getFullyQualifiedTypeName());
394:                 superMethodBuilder.append("\"),this);");
395:                 superMethodBuilder.append("\n\t\t");
396:                 superMethodBuilder.append("this.setThis(this);");
397:                 
398:                 final GenJavaOperation superOperation =
399:                                 GenJavaOperation.create(
400:                                                 "$super",
401:                                                 GenVisibility.PRIVATE,
402:                                                 genParametersWithMap,
403:                                                 new LinkedList<GenException>(),
404:                                                 superMethodBuilder.toString(),
405:                                                 GenVoidType.getInstance(),
406:                                                 new LinkedList<GenOperationModifier>(),
407:                                                 GenComment.create("/**\n\t * Instantiates objects for the super types of this class.\n\t **/"));
408:                 genClassClass.addOperation(superOperation);
409:         }
410:         
411:         /**
412:          * Generates a tuple with the same amount of generic fields as the size of constructorParametersWithoutMap (if it
413:          * does not already exist), a matching getter method in genClassClass that returns a tuple instantiation filled with
414:          * values matching the types of constructorParametersWithoutMap and a call-string to that getter-method including a
415:          * tuple reference with the name tuple_superMethodNumber_superTypeNumber.
416:          *
417:          * @param genClassClass
418:          * the class to generate $super for.
419:          * @param tupleName
420:          * the name of the tuple reference to generate
421:          * @param superTypeName
422:          * the name of the super type for the todo of the getter.
423:          * @param constructorParametersWithoutMap
424:          * the parameters of the super type constructor without $generatedObjects.
425:          * @param genParametersWithoutMap
426:          * the parameters of $super without $generatedObjects.
427:          * @param superMethodNumber
428:          * the number of the super method.
429:          * @param superTypeNumber
430:          * the number of the super type.
431:          * @return a call-string to that getter-method including a tuple reference with the name
432:          * tuple_superMethodNumber_superTypeNumber.
433:          */
434:         private String generateTupleInstantiationStringAndTupleClassAndTupleGetter(final GenClassClass genClassClass,
435:                         final String tupleName,
436:                         final String superTypeName,
437:                         final List<GenParameter> constructorParametersWithoutMap,
438:                         final List<GenParameter> genParametersWithoutMap,
439:                         final int superMethodNumber,
440:                         final int superTypeNumber) {
441:                 final StringBuilder resultStringBuilder = new StringBuilder();
442:                 final StringBuilder genericListStringBuilder = new StringBuilder();
443:                 final Iterator<GenParameter> parameters = constructorParametersWithoutMap.iterator();
444:                 while (parameters.hasNext()) {
445:                         final GenParameter current = parameters.next();
446:                         genericListStringBuilder.append(current.getTyp().getFullyQualifiedNameWithGenericArguments());
447:                         if (parameters.hasNext()) {
448:                                 genericListStringBuilder.append(", ");
449:                         }
450:                 }
451:                 final int genericCount = constructorParametersWithoutMap.size();
452:                 final String superParameterString = this.generateParameterString("", genParametersWithoutMap);
453:                 final String genericString = "<" + genericListStringBuilder.toString() + "> ";
454:                 final String tupleTypePrefix = "generated.Tuple" + genericCount;
455:                 final String tupleTypeString = tupleTypePrefix + genericString;
456:                 final String getterName = "getTuple_" + superMethodNumber + "_" + superTypeNumber;
457:                 resultStringBuilder.append(tupleTypeString);
458:                 resultStringBuilder.append(tupleName);
459:                 resultStringBuilder.append(" = ");
460:                 resultStringBuilder.append("this.");
461:                 resultStringBuilder.append(getterName);
462:                 resultStringBuilder.append("(");
463:                 resultStringBuilder.append(superParameterString);
464:                 resultStringBuilder.append(";");
465:                 final GenUserClass tuple = this.generateTupleClass(genericCount);
466:                 this.generateTupleGetterMethod(
467:                                 genClassClass,
468:                                 getterName,
469:                                 genParametersWithoutMap,
470:                                 constructorParametersWithoutMap,
471:                                 tupleTypeString,
472:                                 tupleTypePrefix,
473:                                 genericString,
474:                                 tuple,
475:                                 superTypeName);
476:                 return resultStringBuilder.toString();
477:         }
478:         
479:         /**
480:          * Generates a tuple class with name Tuple<genericCount> and genericCount generic fields if it does not exist
481:          * already.
482:          *
483:          * @param genericCount
484:          * the amount of generic types.
485:          * @return a tuple class with name Tuple<genericCount> and genericCount generic fields.
486:          */
487:         private GenUserClass generateTupleClass(final int genericCount) {
488:                 if (this.genericTuplesToGenerate.containsKey(genericCount)) {
489:                         return this.genericTuplesToGenerate.get(genericCount);
490:                 }
491:                 final List<Generic> generics = new Vector<>();
492:                 final List<GenJavaOperation> operations = new Vector<>();
493:                 final List<GenJavaAttribute> attributes = new Vector<>();
494:                 final List<GenParameter> constructorParameters = new Vector<>();
495:                 final StringBuilder constructorMethodBuilder = new StringBuilder();
496:                 for (int i = 1; i <= genericCount; i++) {
497:                         final String genericTypeName = "ValueType" + i;
498:                         final String genericAttributeNameSuffix = "alue" + i;
499:                         final String genericAttributeName = "v" + genericAttributeNameSuffix;
500:                         final String genericOperationNameSuffix = "V" + genericAttributeNameSuffix;
501:                         final Generic generic = Generic.create(genericTypeName, GenHasNoGenericType.create());
502:                         generics.add(generic);
503:                         final GenJavaOperation operation =
504:                                         GenJavaOperation.create(
505:                                                         "get" + genericOperationNameSuffix,
506:                                                         new Vector<GenParameter>(),
507:                                                         GenFullParsedOperationState.create(
508:                                                                         GenComment.create("/**\n\t * Returns the value of type " + genericTypeName
509:                                                                                         + ".\n\t **/"),
510:                                                                         new Vector<GenException>(),
511:                                                                         GenTypeReferenceByReference.create(generic),
512:                                                                         new Vector<GenOperationModifier>(),
513:                                                                         GenVisibility.PUBLIC,
514:                                                                         "return this." + genericAttributeName + ";"));
515:                         operations.add(operation);
516:                         final GenJavaAttribute attribute =
517:                                         GenJavaAttribute.create(
518:                                                         genericAttributeName,
519:                                                         GenVisibility.PRIVATE,
520:                                                         generic,
521:                                                         new Vector<GenAttributeModifier>());
522:                         attributes.add(attribute);
523:                         final GenParameter parameter = GenParameter.create(genericAttributeName, generic);
524:                         constructorParameters.add(parameter);
525:                         constructorMethodBuilder
526:                                         .append("this." + genericAttributeName + " = " + genericAttributeName + ";\n\t\t\t");
527:                 }
528:                 
529:                 final GenUserClass tuple =
530:                                 GenUserClass.create(
531:                                                 "Tuple" + genericCount,
532:                                                 operations,
533:                                                 new Vector<GenInterfaceClass>(),
534:                                                 attributes,
535:                                                 new Vector<GenClassModifier>(),
536:                                                 new Vector<GenJavaOperation>(),
537:                                                 null,
538:                                                 GenUnqualifiedPackage.create("generated"),
539:                                                 GenComment.create("/**\n* A tuple with " + genericCount + " generic fields.\n**/"),
540:                                                 "");
541:                 
542:                 tuple.getGenerics().addAll(generics);
543:                 
544:                 final GenJavaOperation constructor =
545:                                 GenJavaOperation.create(
546:                                                 "",
547:                                                 constructorParameters,
548:                                                 GenFullParsedOperationState.create(
549:                                                                 GenComment.create("/**\n\t * Creates a new Tuple" + genericCount + ".\n\t **/"),
550:                                                                 new Vector<GenException>(),
551:                                                                 GenTypeReferenceByReference.create(tuple),
552:                                                                 new Vector<GenOperationModifier>(),
553:                                                                 GenVisibility.PUBLIC,
554:                                                                 constructorMethodBuilder.toString()));
555:                 tuple.getConstructors().add(constructor);
556:                 
557:                 this.generatorModel.addNonAstClass(tuple);
558:                 this.genericTuplesToGenerate.put(genericCount, tuple);
559:                 return tuple;
560:         }
561:         
562:         /**
563:          * Generates the getter method for the tuple of a concrete super constructor call. The generated method enables the
564:          * user to provide the parameters for the super constructor call in a tuple.
565:          *
566:          * @param genClassClass
567:          * the class with $super.
568:          * @param getterName
569:          * the name of the getter.
570:          * @param genParametersWithoutMap
571:          * the parameters of $super without $generatedObjects.
572:          * @param constructorParametersWithoutMap
573:          * the parameters of the super constructor without $generatedObjects.
574:          * @param tupleTypeString
575:          * the concrete type of the tuple as string.
576:          * @param tupleTypePrefix
577:          * the name of the tuple type as string.
578:          * @param genericString
579:          * the string with the generic types of the tuple.
580:          * @param returnType
581:          * the return type of the getter (the tuple itself).
582:          * @param superTypeName
583:          * the name of the super type for the todo comment.
584:          */
585:         private void generateTupleGetterMethod(final GenClassClass genClassClass,
586:                         final String getterName,
587:                         final List<GenParameter> genParametersWithoutMap,
588:                         final List<GenParameter> constructorParametersWithoutMap,
589:                         final String tupleTypeString,
590:                         final String tupleTypePrefix,
591:                         final String genericString,
592:                         final GenType returnType,
593:                         final String superTypeName) {
594:                 final StringBuilder methodStringBuilder =
595:                                 new StringBuilder(
596:                                                 "//TODO replace the following null values with your desired values for the constructor of the super type "
597:                                                                 + superTypeName);
598:                 methodStringBuilder.append("\n\t\t");
599:                 methodStringBuilder.append(tupleTypeString);
600:                 methodStringBuilder.append(" tuple ");
601:                 methodStringBuilder.append("= new ");
602:                 methodStringBuilder.append(tupleTypePrefix);
603:                 methodStringBuilder.append("<>(" + this.generateNullStringWithCasts(constructorParametersWithoutMap) + ");");
604:                 methodStringBuilder.append("\n\t\treturn tuple;");
605:                 
606:                 final GenJavaOperation tupleGetterMethod =
607:                                 GenJavaOperation.create(
608:                                                 genericString + " " + getterName,
609:                                                 genParametersWithoutMap,
610:                                                 GenFullParsedOperationState.create(
611:                                                                 GenComment.create("/**\n\t * Returns a tuple with the parameters for a "
612:                                                                                 + "super constructor." + "\n\t * "
613:                                                                                 + "The name of this operation describes the signature of "
614:                                                                                 + "said constructor." + "\n\t **/"),
615:                                                                 new Vector<GenException>(),
616:                                                                 GenTypeReferenceByReference.create(returnType),
617:                                                                 new Vector<GenOperationModifier>(),
618:                                                                 GenVisibility.PRIVATE,
619:                                                                 methodStringBuilder.toString()));
620:                 genClassClass.addOperation(tupleGetterMethod);
621:                 
622:         }
623:         
624:         /**
625:          * Generates a comma separated parameter string starting with '(' and ending with ')' with as many null values as
626:          * constructorParametersWithoutMap has entries. Adds a cast to the matching parameter type from
627:          * constructorParametersWithoutMap before each null value.
628:          *
629:          * @param constructorParametersWithoutMap
630:          * the parameters to use.
631:          * @return a comma separated parameter string starting with '(' and ending with ')' with as many null values as
632:          * constructorParametersWithoutMap has entries.
633:          */
634:         private String generateNullStringWithCasts(final List<GenParameter> constructorParametersWithoutMap) {
635:                 final StringBuilder resultBuilder = new StringBuilder();
636:                 final Iterator<GenParameter> parameters = constructorParametersWithoutMap.iterator();
637:                 while (parameters.hasNext()) {
638:                         resultBuilder.append("(");
639:                         resultBuilder.append(parameters.next().getTyp().getFullyQualifiedNameWithGenericArguments());
640:                         resultBuilder.append(") null");
641:                         if (parameters.hasNext()) {
642:                                 resultBuilder.append(",");
643:                         }
644:                 }
645:                 return resultBuilder.toString();
646:         }
647:         
648:         /**
649:          * Searches for a constructor in superConstructors that matches superType.
650:          *
651:          * @param superType
652:          * the superType.
653:          * @param superConstructors
654:          * a list of super constructors to call.
655:          * @return the matching constructor.
656:          * @throws TaskException
657:          * is being thrown when no matching constructor can be found in superConstructors.
658:          */
659:         private Constructor getConstructorForType(final Type superType,
660:                         final Collection<ConstructorReference> superConstructors) throws TaskException {
661:                 if (superConstructors.isEmpty()) {
662:                         return Constructor.create(
663:                                         ProductType.create(DummyToken.getInstance()),
664:                                         this.getTypeAsClassType(superType),
665:                                         new LinkedList<ConstructorReference>(),
666:                                         DummyToken.getInstance(),
667:                                         DummyToken.getInstance());
668:                 }
669:                 final Iterator<ConstructorReference> constructorReferences = superConstructors.iterator();
670:                 boolean found = false;
671:                 Constructor constructor = null;
672:                 while (!found && constructorReferences.hasNext()) {
673:                         constructor = this.getConstructorFromConstructorReference(constructorReferences.next());
674:                         found = constructor.getReturnType().equals(superType);
675:                 }
676:                 if (!found) {
677:                         throw new TaskException(
678:                                         "ConstructorCallGenerationTask: No constructor found while trying to generate code snipped for: "
679:                                                         + superType + " in $super!");
680:                 }
681:                 return constructor;
682:         }
683:         
684:         /**
685:          * Tries to find a ClassType for superType.
686:          *
687:          * @param superType
688:          * the type.
689:          * @return a ClassType that is representative for superType.
690:          * @throws TaskException
691:          * if no ClassType for the super type can be found.
692:          */
693:         private ClassType getTypeAsClassType(final Type superType) throws TaskException {
694:                 return superType.accept(new ClassTypeFinder());
695:         }
696:         
697:         /**
698:          * Tries to find a ClassType for superType.
699:          */
700:         private static class ClassTypeFinder implements TypeVisitorReturnException<ClassType, TaskException> {
701:                 
702:                 @Override
703:                 public ClassType handle(final AtomicType atomicType) throws TaskException {
704:                         return atomicType.accept(new AtomicTypeVisitorReturnException<ClassType, TaskException>() {
705:                                 
706:                                 @Override
707:                                 public ClassType handle(final BaseType baseType) throws TaskException {
708:                                         throw new TaskException("ConstructorCallGenerationTask: No BaseType allowed here!");
709:                                 }
710:                                 
711:                                 @Override
712:                                 public ClassType handle(final ClassType clazz) throws TaskException {
713:                                         return clazz;
714:                                 }
715:                                 
716:                         });
717:                 }
718:                 
719:                 @Override
720:                 public ClassType handle(final CompositeType compositeType) throws TaskException {
721:                         throw new TaskException("ConstructorCallGenerationTask: No SumType allowed here!");
722:                 }
723:                 
724:                 @Override
725:                 public ClassType handle(final TypeProxy typeProxy) throws TaskException {
726:                         return typeProxy.getTarget().accept(this);
727:                 }
728:                 
729:         }
730:         
731:         /**
732:          * Gets the constructor for reference.
733:          *
734:          * @param reference
735:          * the reference.
736:          * @return a constructor that is referenced via reference.
737:          * @throws TaskException
738:          * if no constructor can be found (Wrong reference state).
739:          */
740:         private Constructor getConstructorFromConstructorReference(final ConstructorReference reference)
741:                         throws TaskException {
742:                 /**
743:                  * Message if reference is in wrong state.
744:                  */
745:                 final String exceptionMessage =
746:                                 "ConstructorCallGenerationTask: ConstructorReference"
747:                                                 + " needs to be in ConstructorByReferenceState at this point. Current state: ";
748:                 
749:                 return reference.getState().accept(
750:                                 new ConstructorReferenceStateVisitorReturnException<Constructor, TaskException>() {
751:                                         
752:                                         @Override
753:                                         public Constructor handle(final ConstructorByTypeAndSignatureState byName) throws TaskException {
754:                                                 throw new TaskException(exceptionMessage + byName);
755:                                         }
756:                                         
757:                                         @Override
758:                                         public Constructor handle(final ConstructorInvalidState invalid) throws TaskException {
759:                                                 throw new TaskException(exceptionMessage + invalid);
760:                                         }
761:                                         
762:                                         @Override
763:                                         public Constructor handle(final ConstructorByReferenceState byReference) {
764:                                                 return byReference.getTarget();
765:                                         }
766:                                         
767:                                 });
768:         }
769:         
770:         /**
771:          * Creates GenParameters for parameters.
772:          *
773:          * @param parameters
774:          * the parameters to generate.
775:          * @return GenParameters that match parameters.
776:          * @throws GenTypeNotReferencedException
777:          * if no genType for a parameter type can be found.
778:          */
779:         private List<GenParameter> createGenParameters(final ProductType parameters) throws GenTypeNotReferencedException {
780:                 final List<ProductElementType> elements = parameters.getElements();
781:                 final List<GenParameter> result = new LinkedList<>();
782:                 for (final ProductElementType productElement : elements) {
783:                         final GenType paramType = this.generatorModel.getGenTypeForType(productElement.getType());
784:                         result.add(GenParameter.create(productElement.getName(), paramType));
785:                 }
786:                 return result;
787:         }
788:         
789:         /**
790:          * D Generates a constructor.
791:          *
792:          * @param genClassClass
793:          * for class.
794:          * @param genParameters
795:          * with parameters.
796:          * @param methodBody
797:          * with implementation.
798:          * @param visibility
799:          */
800:         private void generateConstructor(final GenClassClass genClassClass,
801:                         final List<GenParameter> genParameters,
802:                         final String methodBody,
803:                         final GenVisibility visibility) {
804:                 final GenComment comment =
805:                                 GenComment
806:                                                 .create("/** \n\t * " + "Creates an instance of type " + genClassClass.getName() + "\n\t **/");
807:                 final GenJavaOperation constructorWithMap =
808:                                 GenJavaOperation.create(
809:                                                 "",
810:                                                 visibility,
811:                                                 genParameters,
812:                                                 new Vector<GenException>(),
813:                                                 methodBody,
814:                                                 genClassClass,
815:                                                 new Vector<GenOperationModifier>(),
816:                                                 comment);
817:                 genClassClass.addConstructor(constructorWithMap);
818:         }
819:         
820:         /**
821:          * Generates a call to a $super-Method with genParameters.
822:          *
823:          * @param genParametersWithMap
824:          * will be added (as names) to the call.
825:          * @param genParameters
826:          * @return a $super-call.
827:          */
828:         private String generateSuperCall(final List<GenParameter> genParametersWithMap,
829:                         final List<GenParameter> genParameters) {
830:                 return "this.$super(" + this.generateParameterString("", genParametersWithMap) + ";"
831:                                 + "\n\t\tthis.initializeOnCreation(" + this.generateParameterString("", genParameters) + ";";
832:         }
833:         
834:         /**
835:          * Generates a String with the names of the parameters (comma separated and with a ')' at the end).
836:          *
837:          * @param prefix
838:          * THe Prefix to add to the list.
839:          *
840:          * @param genParameters
841:          * parameters to include.
842:          * @return the parameter-string.
843:          */
844:         private String generateParameterString(final String prefix, final List<GenParameter> genParameters) {
845:                 final StringBuilder superCall = new StringBuilder(prefix);
846:                 final Iterator<GenParameter> parameterIterator = genParameters.iterator();
847:                 while (parameterIterator.hasNext()) {
848:                         final GenParameter parameter = parameterIterator.next();
849:                         superCall.append(parameter.getName());
850:                         if (parameterIterator.hasNext()) {
851:                                 superCall.append(", ");
852:                         }
853:                 }
854:                 superCall.append(")");
855:                 return superCall.toString();
856:         }
857:         
858:         private String generateTupleGetterAndCallString(final String tupleName,
859:                         final List<GenParameter> constructorParametersWithoutMap) {
860:                 final StringBuilder call = new StringBuilder();
861:                 int genericFieldCount = 0;
862:                 final Iterator<GenParameter> parameters = constructorParametersWithoutMap.iterator();
863:                 while (parameters.hasNext()) {
864:                         genericFieldCount++;
865:                         final GenParameter current = parameters.next();
866:                         call.append(tupleName);
867:                         call.append(".<");
868:                         call.append(current.getTyp().getFullyQualifiedNameWithGenericArguments());
869:                         call.append(">getValue");
870:                         call.append(genericFieldCount);
871:                         call.append("(");
872:                         call.append(")");
873:                         if (parameters.hasNext()) {
874:                                 call.append(", ");
875:                         }
876:                 }
877:                 call.append(")");
878:                 return call.toString();
879:         }
880:         
881:         @Override
882:         public void handleGroup(final Group g) throws TaskException {
883:                 // Nothing to do.
884:                 
885:         }
886:         
887:         @Override
888:         public void handleAttribute(final Attribute a, final ClassType owner) throws TaskException {
889:                 // Nothing to do.
890:         }
891:         
892:         @Override
893:         public void handleConstructorOrOperation(final ConstructorOrOperation coo, final ClassType owner)
894:                         throws TaskException {
895:                 // Nothing to do.
896:         }
897:         
898:         @Override
899:         public void finalizeTask() throws TaskException {
900:                 // Nothing to do.
901:         }
902:         
903:         @Override
904:         public void beginTask() throws TaskException {
905:                 // Nothing to do.
906:         }
907:         
908: }