public ValidGraphPath[] generateValidPaths(int graphValidPathCount) { // initialize valid graph paths ValidGraphPath[] validPaths = new ValidGraphPath[graphValidPathCount]; for (int graphIdx = 0; graphIdx < graphValidPathCount; graphIdx++) { validPaths[graphIdx] = new ValidGraphPath(this.graphDepth); } List<ITypeReference> allInterfacesList = this.graphInterfaces.Keys.OfType<ITypeReference>().ToList<ITypeReference>(); PossibleNode[] currentRoundBasePossibleNodes = new PossibleNode[graphValidPathCount]; // generate valid paths for (int idx = 0; idx < this.graphDepth; idx++) { // initialize path element for (int validPathIdx = 0; validPathIdx < graphValidPathCount; validPathIdx++) { validPaths[validPathIdx].pathElements[idx] = new PathElement(); validPaths[validPathIdx].pathElements[idx].validPathId = validPathIdx; if (idx != 0) { validPaths[validPathIdx].pathIndices[idx] = this.prng.Next(this.graphDimension); } else { // mark path index of start node as -1 validPaths[validPathIdx].pathIndices[0] = -1; } } // check if it is the first element of the valid path // => always the root for each valid path if (idx == 0) { // get random base class that is used to generate the valid path element (use it for all first elements of the valid paths) ITypeReference baseInterface = allInterfacesList.ElementAt(this.prng.Next(allInterfacesList.Count())); List<PossibleNode> baseList = (List<PossibleNode>)this.graphInterfaces[baseInterface]; PossibleNode basePossibleNode = baseList.ElementAt(this.prng.Next(baseList.Count())); // for each valid path add a path element for (int validPathIdx = 0; validPathIdx < graphValidPathCount; validPathIdx++) { // get valid interface ITypeReference firstInterface = basePossibleNode.givenClass.Interfaces.ElementAt(this.prng.Next(basePossibleNode.givenClass.Interfaces.Count())); validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(firstInterface); // add interface to mandatory list (if it is not already in it) if (!validPaths[0].pathElements[idx].mandatoryInterfaces.Contains(firstInterface)) { validPaths[0].pathElements[idx].mandatoryInterfaces.Add(firstInterface); } // add valid interfaces to the path element bool addAnotherInterface = true; int addInterfaceWeight = 3; while (addAnotherInterface) { // decide wether to add another valid interface or not switch (this.prng.Next(addInterfaceWeight)) { // add another interface to the list of valid interfaces case 0: case 1: { // check if there exists more interfaces that could be added to the list of valid interfaces if (basePossibleNode.givenClass.Interfaces.Count() == validPaths[validPathIdx].pathElements[idx].validInterfaces.Count()) { addAnotherInterface = false; break; } // add a random interface that is implemented by the base possible node int nextInterfaceIdx = this.prng.Next(basePossibleNode.givenClass.Interfaces.Count()); while (true) { ITypeReference tempInterface = basePossibleNode.givenClass.Interfaces.ElementAt(nextInterfaceIdx); // check if chosen interface is already added to the list of valid interfaces // => try next interface implemented by the base possible node if (validPaths[validPathIdx].pathElements[idx].validInterfaces.Contains(tempInterface)) { nextInterfaceIdx = (nextInterfaceIdx + 1) % basePossibleNode.givenClass.Interfaces.Count(); } // => add interface to list of valid interfaces else { validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(tempInterface); // add interface to mandatory list (if it is not already in it) if (!validPaths[0].pathElements[idx].mandatoryInterfaces.Contains(tempInterface)) { validPaths[0].pathElements[idx].mandatoryInterfaces.Add(tempInterface); } break; } } break; } //do not add any more interfaces default: { addAnotherInterface = false; break; } } // make adding another invalid interface more unlikely addInterfaceWeight++; } // add invalid interfaces to the path element addAnotherInterface = true; addInterfaceWeight = 2; while (addAnotherInterface) { // decide wether to add another valid interface or not switch (this.prng.Next(addInterfaceWeight)) { // add another interface to the list of invalid interfaces case 0: case 1: { // check if there exists anymore interfaces that could be added to the list of invalid interfaces if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) { if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) { addAnotherInterface = false; break; } throw new ArgumentException("The sum of valid and invalid interfaces should never be greater than the count of all interfaces."); } // check if there exists anymore interfaces that could be added to the list of invalid interfaces if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) { if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) { addAnotherInterface = false; break; } throw new ArgumentException("The sum of implemented and invalid interfaces should never be greater than the count of all interfaces."); } // add a random interface that is NOT implemented by the base possible node int nextInterfaceIdx = this.prng.Next(allInterfacesList.Count()); while (true) { ITypeReference tempInterface = allInterfacesList.ElementAt(nextInterfaceIdx); // check if chosen interface is NOT added to the list of invalid interfaces // and NOT implemented by the base possible node // => if it is try next interface of all interfaces if (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Contains(tempInterface) || basePossibleNode.givenClass.Interfaces.Contains(tempInterface)) { nextInterfaceIdx = (nextInterfaceIdx + 1) % allInterfacesList.Count(); } // => add interface to list of invalid interfaces else { validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Add(tempInterface); // add interface to forbidden list (if it is not already in it) if (!validPaths[0].pathElements[idx].forbiddenInterfaces.Contains(tempInterface)) { validPaths[0].pathElements[idx].forbiddenInterfaces.Add(tempInterface); } break; } } break; } //do not add any more interfaces default: { addAnotherInterface = false; break; } } // make adding another invalid interface more unlikely addInterfaceWeight++; } } } // => not the first element of the valid paths else { // for each valid path add a path element for (int validPathIdx = 0; validPathIdx < graphValidPathCount; validPathIdx++) { // if the valid path id is not the first // => search through all already chosen valid paths if the current path is the same until now // and get the idx of this valid path (the first occurring is all that is needed) int samePathIdx = -1; if (validPathIdx != 0) { for(int tempPathIdx = 0; tempPathIdx < validPathIdx; tempPathIdx++) { bool samePath = true; for(int depth = 0; depth <= idx; depth++) { if(validPaths[tempPathIdx].pathIndices[depth] != validPaths[validPathIdx].pathIndices[depth]) { samePath = false; break; } } if(samePath) { samePathIdx = tempPathIdx; break; } } } // if there does not exist a path that is the same up to this point // => chose a random base possible node PossibleNode basePossibleNode; if (samePathIdx == -1) { // get random base class that is used to generate the valid path element ITypeReference baseInterface = allInterfacesList.ElementAt(this.prng.Next(allInterfacesList.Count())); validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(baseInterface); List<PossibleNode> baseList = (List<PossibleNode>)this.graphInterfaces[baseInterface]; basePossibleNode = baseList.ElementAt(this.prng.Next(baseList.Count())); // add interface to mandatory list (if it is not already in it) if (!validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Contains(baseInterface)) { validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Add(baseInterface); } } // if there already exists a path // => use the same base possible node else { basePossibleNode = currentRoundBasePossibleNodes[samePathIdx]; ITypeReference baseInterface = basePossibleNode.givenClass.Interfaces.ElementAt(this.prng.Next(basePossibleNode.givenClass.Interfaces.Count())); validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(baseInterface); // add interface to mandatory list (if it is not already in it) if (!validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Contains(baseInterface)) { validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Add(baseInterface); } } // add valid interfaces to the path element bool addAnotherInterface = true; int addInterfaceWeight = 3; while (addAnotherInterface) { // decide wether to add another valid interface or not switch (this.prng.Next(addInterfaceWeight)) { // add another interface to the list of valid interfaces case 0: case 1: { // check if there exists more interfaces that could be added to the list of valid interfaces if (basePossibleNode.givenClass.Interfaces.Count() == validPaths[validPathIdx].pathElements[idx].validInterfaces.Count()) { addAnotherInterface = false; break; } // add a random interface that is implemented by the base possible node int nextInterfaceIdx = this.prng.Next(basePossibleNode.givenClass.Interfaces.Count()); while (true) { ITypeReference tempInterface = basePossibleNode.givenClass.Interfaces.ElementAt(nextInterfaceIdx); // check if chosen interface is already added to the list of valid interfaces // => try next interface implemented by the base possible node if (validPaths[validPathIdx].pathElements[idx].validInterfaces.Contains(tempInterface)) { nextInterfaceIdx = (nextInterfaceIdx + 1) % basePossibleNode.givenClass.Interfaces.Count(); } // => add interface to list of valid interfaces else { validPaths[validPathIdx].pathElements[idx].validInterfaces.Add(tempInterface); // check if there exist a prior path that has an element at the same position // => if not, add interface to list of mandatory interfaces of this path if (samePathIdx == -1) { if (!validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Contains(tempInterface)) { validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces.Add(tempInterface); } } // => if there is, add interface to list of mandatory interfaces of the prior path else { if (!validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Contains(tempInterface)) { validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces.Add(tempInterface); } } break; } } break; } //do not add any more interfaces default: { addAnotherInterface = false; break; } } // make adding another invalid interface more unlikely addInterfaceWeight++; } // add invalid interfaces to the path element addAnotherInterface = true; addInterfaceWeight = 2; while (addAnotherInterface) { // decide wether to add another valid interface or not switch (this.prng.Next(addInterfaceWeight)) { // add another interface to the list of invalid interfaces case 0: case 1: { // check if there exists anymore interfaces that could be added to the list of invalid interfaces if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) { if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + validPaths[validPathIdx].pathElements[idx].validInterfaces.Count())) { addAnotherInterface = false; break; } throw new ArgumentException("The sum of valid and invalid interfaces should never be greater than the count of all interfaces."); } // check if there exists anymore interfaces that could be added to the list of invalid interfaces if (allInterfacesList.Count() <= (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) { if (allInterfacesList.Count() == (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Count() + basePossibleNode.givenClass.Interfaces.Count())) { addAnotherInterface = false; break; } throw new ArgumentException("The sum of implemented and invalid interfaces should never be greater than the count of all interfaces."); } // add a random interface that is NOT implemented by the base possible node int nextInterfaceIdx = this.prng.Next(allInterfacesList.Count()); while (true) { ITypeReference tempInterface = allInterfacesList.ElementAt(nextInterfaceIdx); // check if chosen interface is NOT added to the list of invalid interfaces // and NOT implemented by the base possible node // => if it is try next interface of all interfaces if (validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Contains(tempInterface) || basePossibleNode.givenClass.Interfaces.Contains(tempInterface)) { nextInterfaceIdx = (nextInterfaceIdx + 1) % allInterfacesList.Count(); } // => add interface to list of invalid interfaces else { validPaths[validPathIdx].pathElements[idx].invalidInterfaces.Add(tempInterface); // check if there exist a prior path that has an element at the same position // => if not, add interface to list of forbidden interfaces of this path if (samePathIdx == -1) { if (!validPaths[validPathIdx].pathElements[idx].forbiddenInterfaces.Contains(tempInterface)) { validPaths[validPathIdx].pathElements[idx].forbiddenInterfaces.Add(tempInterface); } } // => if there is, add interface to list of forbidden interfaces of the prior path else { if (!validPaths[samePathIdx].pathElements[idx].forbiddenInterfaces.Contains(tempInterface)) { validPaths[samePathIdx].pathElements[idx].forbiddenInterfaces.Add(tempInterface); } } break; } } break; } //do not add any more interfaces default: { addAnotherInterface = false; break; } } // make adding another invalid interface more unlikely addInterfaceWeight++; } // add current base possible node to the current round base possible nodes currentRoundBasePossibleNodes[validPathIdx] = basePossibleNode; } } } // set all mandatory and forbidden interfaces lists of all nodes that lie on the same path for (int idx = 0; idx < this.graphDepth; idx++) { for (int validPathIdx = 1; validPathIdx < graphValidPathCount; validPathIdx++) { // search through all prior valid paths if the current path is the same until now // and get the idx of this valid path (the first occurring is all that is needed) int samePathIdx = -1; for (int tempPathIdx = 0; tempPathIdx < validPathIdx; tempPathIdx++) { bool samePath = true; for (int depth = 0; depth <= idx; depth++) { if (validPaths[tempPathIdx].pathIndices[depth] != validPaths[validPathIdx].pathIndices[depth]) { samePath = false; break; } } if (samePath) { samePathIdx = tempPathIdx; break; } } // if a path was found which is the same up to the current point // => set the mandatory and forbidden list to the lists of the found path if (samePathIdx != -1) { validPaths[validPathIdx].pathElements[idx].mandatoryInterfaces = validPaths[samePathIdx].pathElements[idx].mandatoryInterfaces; validPaths[validPathIdx].pathElements[idx].forbiddenInterfaces = validPaths[samePathIdx].pathElements[idx].forbiddenInterfaces; } } } return validPaths; }
// this function adds the created iNode interface to the class and also implements all neded functions public void addNodeInterfaceToTargetClass(NamespaceTypeDefinition givenClass) { this.logger.writeLine(""); this.logger.writeLine("Add node interface \"" + this.nodeInterface.ToString() + "\" to class \"" + givenClass.ToString() + "\""); // check if generated interface was already added to target class if (givenClass.Interfaces != null && givenClass.Interfaces.Contains(this.nodeInterface)) { this.logger.writeLine("Class \"" + givenClass.ToString() + "\" already contains node interface \"" + this.nodeInterface.ToString() + "\""); return; } // add nodes interface to class if (givenClass.Interfaces != null) { givenClass.Interfaces.Add(this.nodeInterface); } else { givenClass.Interfaces = new List<ITypeReference>(); givenClass.Interfaces.Add(this.nodeInterface); } // add start pointer field FieldDefinition startPointerField = new FieldDefinition(); startPointerField.IsCompileTimeConstant = false; startPointerField.IsNotSerialized = false; startPointerField.IsReadOnly = false; startPointerField.IsRuntimeSpecial = false; startPointerField.IsSpecialName = false; startPointerField.Type = this.nodeInterface; startPointerField.IsStatic = false; startPointerField.Visibility = TypeMemberVisibility.Public; startPointerField.Name = host.NameTable.GetNameFor("startPointer"); startPointerField.InternFactory = host.InternFactory; startPointerField.ContainingTypeDefinition = givenClass; if (givenClass.Fields != null) { givenClass.Fields.Add(startPointerField); } else { givenClass.Fields = new List<IFieldDefinition>(); givenClass.Fields.Add(startPointerField); } // create getter for the startPointer variable MethodDefinition startPointerGetMethod = this.helperClass.createNewMethod("startPointer_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name // create a body for the getter method ILGenerator ilGenerator = new ILGenerator(host, startPointerGetMethod); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldfld, startPointerField); ilGenerator.Emit(OperationCode.Ret); IMethodBody body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty); startPointerGetMethod.Body = body; // create setter for the startPointer variable List<IParameterDefinition> parameters = new List<IParameterDefinition>(); ParameterDefinition parameter = new ParameterDefinition(); parameter.IsIn = false; parameter.IsOptional = false; parameter.IsOut = false; parameter.Name = host.NameTable.GetNameFor("value"); parameter.Type = this.nodeInterface; parameters.Add(parameter); MethodDefinition startPointerSetMethod = this.helperClass.createNewMethod("startPointer_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name // create a body for the setter method ilGenerator = new ILGenerator(host, startPointerSetMethod); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Stfld, startPointerField); ilGenerator.Emit(OperationCode.Ret); body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty); startPointerSetMethod.Body = body; // add childNodes array field FieldDefinition childNodesField = new FieldDefinition(); childNodesField.IsCompileTimeConstant = false; childNodesField.IsNotSerialized = false; childNodesField.IsReadOnly = false; childNodesField.IsRuntimeSpecial = false; childNodesField.IsSpecialName = false; // create array of node interface type VectorTypeReference nodeInterfaceArrayType = new VectorTypeReference(); nodeInterfaceArrayType.ElementType = this.nodeInterface; nodeInterfaceArrayType.Rank = 1; nodeInterfaceArrayType.IsFrozen = true; nodeInterfaceArrayType.IsValueType = false; nodeInterfaceArrayType.InternFactory = host.InternFactory; childNodesField.Type = nodeInterfaceArrayType; childNodesField.IsStatic = false; childNodesField.Visibility = TypeMemberVisibility.Public; childNodesField.Name = host.NameTable.GetNameFor("childNodes"); childNodesField.InternFactory = host.InternFactory; childNodesField.ContainingTypeDefinition = givenClass; givenClass.Fields.Add(childNodesField); // create getter for the childNodes variable parameters = new List<IParameterDefinition>(); // int parameter parameter = new ParameterDefinition(); parameter.IsIn = false; parameter.IsOptional = false; parameter.IsOut = false; parameter.Type = this.host.PlatformType.SystemInt32; parameters.Add(parameter); MethodDefinition childNodesGetMethod = this.helperClass.createNewMethod("childNodes_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name // create a body for the getter method ilGenerator = new ILGenerator(host, childNodesGetMethod); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldfld, childNodesField); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Ldelem_Ref); ilGenerator.Emit(OperationCode.Ret); body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty); childNodesGetMethod.Body = body; // create setter for the childNodes variable parameters = new List<IParameterDefinition>(); // iNode parameter parameter = new ParameterDefinition(); parameter.IsIn = false; parameter.IsOptional = false; parameter.IsOut = false; parameter.Type = this.nodeInterface; parameters.Add(parameter); // int parameter parameter = new ParameterDefinition(); parameter.IsIn = false; parameter.IsOptional = false; parameter.IsOut = false; parameter.Type = this.host.PlatformType.SystemInt32; parameters.Add(parameter); MethodDefinition childNodesSetMethod = this.helperClass.createNewMethod("childNodes_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name // create a body for the setter method ilGenerator = new ILGenerator(host, childNodesSetMethod); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldfld, childNodesField); ilGenerator.Emit(OperationCode.Ldarg_2); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Stelem_Ref); ilGenerator.Emit(OperationCode.Ret); body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty); childNodesSetMethod.Body = body; // add current node field FieldDefinition currentNodeField = new FieldDefinition(); currentNodeField.IsCompileTimeConstant = false; currentNodeField.IsNotSerialized = false; currentNodeField.IsReadOnly = false; currentNodeField.IsRuntimeSpecial = false; currentNodeField.IsSpecialName = false; currentNodeField.Type = this.nodeInterface; currentNodeField.IsStatic = false; currentNodeField.Visibility = TypeMemberVisibility.Public; currentNodeField.Name = host.NameTable.GetNameFor("currentNode"); currentNodeField.InternFactory = host.InternFactory; currentNodeField.ContainingTypeDefinition = givenClass; givenClass.Fields.Add(currentNodeField); // create getter for the currentNode variable MethodDefinition currentNodeGetMethod = this.helperClass.createNewMethod("currentNode_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name // create a body for the getter method ilGenerator = new ILGenerator(host, currentNodeGetMethod); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldfld, currentNodeField); ilGenerator.Emit(OperationCode.Ret); body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty); currentNodeGetMethod.Body = body; // create setter for the currentNode variable parameters = new List<IParameterDefinition>(); parameter = new ParameterDefinition(); parameter.IsIn = false; parameter.IsOptional = false; parameter.IsOut = false; parameter.Name = host.NameTable.GetNameFor("value"); parameter.Type = this.nodeInterface; parameters.Add(parameter); MethodDefinition currentNodeSetMethod = this.helperClass.createNewMethod("currentNode_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name // create a body for the setter method ilGenerator = new ILGenerator(host, currentNodeSetMethod); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Stfld, currentNodeField); ilGenerator.Emit(OperationCode.Ret); body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty); currentNodeSetMethod.Body = body; // check if debugging is activated // => add graph debugging attributes and methods MethodDefinition objectIdGetMethod = null; FieldDefinition objectIdField = null; if (this.debugging) { this.logger.writeLine("Debugging activated: Adding field for unique object id and getter method"); // add objectId field objectIdField = new FieldDefinition(); objectIdField.IsCompileTimeConstant = false; objectIdField.IsNotSerialized = false; objectIdField.IsReadOnly = false; objectIdField.IsRuntimeSpecial = false; objectIdField.IsSpecialName = false; objectIdField.Type = this.host.PlatformType.SystemString; objectIdField.IsStatic = false; objectIdField.Name = host.NameTable.GetNameFor("DEBUG_objectId"); objectIdField.Visibility = TypeMemberVisibility.Public; objectIdField.InternFactory = host.InternFactory; objectIdField.ContainingTypeDefinition = givenClass; givenClass.Fields.Add(objectIdField); // create getter for the objectId variable objectIdGetMethod = this.helperClass.createNewMethod("DEBUG_objectId_get", givenClass, this.host.PlatformType.SystemString, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name // create a body for the getter method ilGenerator = new ILGenerator(host, objectIdGetMethod); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldfld, objectIdField); ilGenerator.Emit(OperationCode.Ret); body = new ILGeneratorMethodBody(ilGenerator, true, 1, objectIdGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty); objectIdGetMethod.Body = body; } // add .ctor(iNode) to target class parameters = new List<IParameterDefinition>(); parameter = new ParameterDefinition(); parameter.IsIn = false; parameter.IsOptional = false; parameter.IsOut = false; parameter.Type = this.nodeInterface; parameters.Add(parameter); MethodDefinition nodeConstructor = this.helperClass.createNewMethod(".ctor", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, false); nodeConstructor.IsSpecialName = true; nodeConstructor.IsHiddenBySignature = true; nodeConstructor.IsRuntimeSpecial = true; // generate node constructor body ilGenerator = new ILGenerator(host, currentNodeSetMethod); // create local variable list List<ILocalDefinition> localVariables = new List<ILocalDefinition>(); // call system.object constructor ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Call, this.helperClass.objectCtor); // initialize childNodes array ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension); ilGenerator.Emit(OperationCode.Newarr, nodeInterfaceArrayType); ilGenerator.Emit(OperationCode.Stfld, childNodesField); // check if debugging is activated // => add code to constructor that generates a unique id for this object if (this.debugging) { this.logger.writeLine("Debugging activated: Adding code to generate unique id to node constructor"); // create local integer variable needed for debugging code LocalDefinition intLocal = new LocalDefinition(); intLocal.IsReference = false; intLocal.IsPinned = false; intLocal.IsModified = false; intLocal.Type = this.host.PlatformType.SystemInt32; intLocal.MethodDefinition = nodeConstructor; localVariables.Add(intLocal); // use the hash code of this instance as unique object id ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.objectGetHashCode); ilGenerator.Emit(OperationCode.Stloc, intLocal); // cast random integer to string and store in object id ilGenerator.Emit(OperationCode.Ldloca, intLocal); ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString); ilGenerator.Emit(OperationCode.Stfld, objectIdField); } ilGenerator.Emit(OperationCode.Ret); body = new ILGeneratorMethodBody(ilGenerator, true, 8, nodeConstructor, localVariables, Enumerable<ITypeDefinition>.Empty); nodeConstructor.Body = body; // add class to the list of possible nodes for the graph PossibleNode tempStruct = new PossibleNode(); tempStruct.nodeConstructor = nodeConstructor; tempStruct.givenClass = givenClass; // for each interface the class implements add it to the according list foreach (ITypeReference interfaceRef in givenClass.Interfaces) { this.logger.writeLine("Add class \"" + givenClass.ToString() + "\" to graph interface list \"" + interfaceRef.ToString() + "\""); // check if a list with this interface already exists // => if it does just add current class to list if (this.graphInterfaces.ContainsKey(interfaceRef)) { List<PossibleNode> tempList = (List<PossibleNode>)this.graphInterfaces[interfaceRef]; tempList.Add(tempStruct); } // if not => add new list for this interface else { List<PossibleNode> tempList = new List<PossibleNode>(); tempList.Add(tempStruct); this.graphInterfaces.Add(interfaceRef, tempList); } } this.logger.writeLine(""); }