Ejemplo n.º 1
0
        public static NaiadSerialization <T> GetSerializer <T>()
        {
            lock (_codegenLock)
            {
                Type t = typeof(T);

                if (!_codeGenCache.ContainsKey(t))
                {
                    var    gen        = new NaiadSerializationCodeGenerator(t);
                    object serializer = CompileSerializationCode(gen);
                    _codeGenCache[t] = serializer;
                }

                return((NaiadSerialization <T>)_codeGenCache[t]);
            }
        }
Ejemplo n.º 2
0
        private static object CompileSerializationCode(NaiadSerializationCodeGenerator codeGen)
        {
            Tracing.Trace("[Compile");
            CodeCompileUnit compileUnit = codeGen.CompileUnit;

            using (var codeProvider = new CSharpCodeProvider())
            {
                using (var sourceStream = new StringWriter())
                {
                    var codeGenOpts = new CodeGeneratorOptions();
                    codeGenOpts.BlankLinesBetweenMembers = true;
                    codeGenOpts.ElseOnClosing            = true;
                    codeGenOpts.BracingStyle             = "Block";
                    codeGenOpts.IndentString             = "  ";


                    codeProvider.GenerateCodeFromCompileUnit(compileUnit, sourceStream, codeGenOpts);

                    var sourceData = sourceStream.ToString();

                    //_compileCache.Lock();

                    var cachedAssembly = _compileCache.Load(sourceData);
                    if (cachedAssembly != null)
                    {
                        // Logging.Info("Found cached assembly for {0}", codeGen.CodeGenClass);
                        return(cachedAssembly.CreateInstance(String.Format("Naiad.AutoGenerated.{0}", codeGen.CodeGenClass)));
                    }

                    var sourcePath = FileNameForType(codeGen.Type);
                    sourcePath = BadClassChars.Replace(sourcePath, "_");
                    sourcePath = Path.Combine(_compileCache.SourceDir, sourcePath + ".cs");
                    sourcePath = Path.GetFullPath(sourcePath);

                    // Delete any pre-existing source file.
                    File.Delete(sourcePath);

                    File.WriteAllText(sourcePath, sourceData);

                    Logging.Info("Compiling codegen for {0}", codeGen.CodeGenClass);

                    var compilerOpts = new CompilerParameters();
                    compilerOpts.GenerateInMemory = false;
#if DEBUG
                    compilerOpts.CompilerOptions = "/debug";
#else
                    compilerOpts.CompilerOptions       = "/optimize+";
                    compilerOpts.TreatWarningsAsErrors = false;
#endif
                    compilerOpts.IncludeDebugInformation = true;

                    compilerOpts.ReferencedAssemblies.Add("System.dll");
                    compilerOpts.ReferencedAssemblies.Add("System.Core.dll");

                    foreach (var assembly in codeGen.GeneratedTypes.Select(Assembly.GetAssembly).Distinct())
                    {
                        compilerOpts.ReferencedAssemblies.Add(assembly.Location);
                    }

                    compilerOpts.ReferencedAssemblies.Add(typeof(AutoSerialization).Assembly.Location);

                    compilerOpts.GenerateInMemory = false; //default

                    compilerOpts.TempFiles = new TempFileCollection(_compileCache.ObjectDir, true);
                    compilerOpts.IncludeDebugInformation = true;
                    compilerOpts.TempFiles.KeepFiles     = true;

                    //var res = codeProvider.CompileAssemblyFromFile(compilerOpts, sourcePath);
                    var res = codeProvider.CompileAssemblyFromSource(compilerOpts, new string[] { sourceData });

                    if (res.Errors.Count > 0)
                    {
                        var errorMsg = res.Errors.Cast <CompilerError>().Aggregate("", (current, ce) => current + (ce + "\n"));
                        var msg      = "Compile failed:" + errorMsg;
                        Logging.Error("{0}", msg);

                        throw new Exception(msg);
                    }

                    Logging.Info("Assembly: {0}", res.PathToAssembly);
                    _compileCache.Store(sourceData, res.PathToAssembly);

                    //_compileCache.Unlock();
                    Tracing.Trace("]Compile");

                    return(res.CompiledAssembly.CreateInstance(String.Format("Naiad.AutoGenerated.{0}", codeGen.CodeGenClass)));
                }
            }
        }