//TODO: Move to separate file /// <summary> /// Adds a list of Declarations to the valuestore and initializes them. /// The initialization is done by compiling a function that initializes the variables with /// the same Function calls the user used. /// </summary> /// <param name="declarations"></param> internal static void AddDeclarations(ISession session, IList<Declaration> declarations) { //start with a ; so when we later try to add return to the front we will get return; //inside a object() function, which will throw a compiler error. We want this behaviour as we dont want to //get a return i = 0. This would result in no compiler error thus leaving the function at the very first //assignment when invoked and thus resulting in unwanted behaviour. string source = ";\r\n"; //Next Add all our Variables we want to declare. By now they are in the Valuestore but dont have a value yet. //we now call Code that assigns them their values as specified by the user. foreach (Declaration decl in declarations) { object obj = new object(); session.AddVariable(decl.Name, new ValuePointer(() => obj, (o) => obj = o, decl.Type, decl.IsDynamic)); source += String.Format("{0} = {1};\r\n", decl.Name, decl.InitializationString); } //Now we build the Assembly and call the method to initialize the variables CompilerResults results = AssemblyGenerator.Build(session.NewRequest(source)); if (!results.Errors.HasErrors) //Check if we have encountered errors during Compilation { Type wrapperClass = results.CompiledAssembly.GetType("Wrapper"); //get a Reference to the Wrapper class MethodInfo evalMethod = wrapperClass.GetMethod("Eval", BindingFlags.Static | BindingFlags.Public); //Look for the Eval Method try { //Now we call the method. since we dont ever use any console calls herer we can pass null for out and err textwriters //we also surround with a try catch as we always expect a NoReturnException here. //the rest of the code will be handled in the catch. evalMethod.Invoke(null, new object[] { null, null }); } catch (TargetInvocationException ex) { if (!(ex.InnerException is DebugUtilsV2.Exceptions.NoReturnException)) //trigger remove of values if we encountered an unexpected exception. because if we do, the users initializations were bad { RemoveDeclarationsFromValueStore(session, declarations); throw; //rethrow error as it is unexpected } else //we got the noreturn error, which we expected. now we lock the type of vars { foreach (Declaration decl in declarations) { if (decl.Type == null && !decl.IsDynamic) //check for vars. those will now get locked in their type { session.VariableStore[decl.Name].UpdateToCurrentType(); } } } //Notify the session of our new items session.NotifyChanged(declarations.Select(decl => decl.Name)); } } else { RemoveDeclarationsFromValueStore(session, declarations); } }