Пример #1
0
        public List <string> WriteSource(List <ITypeDeclaration> typeDeclarations, IList <string> filenames, out ICollection <Assembly> referencedAssemblies)
        {
            Stopwatch watch = null;

            if (showProgress)
            {
                watch = new Stopwatch();
                watch.Start();
            }
            List <string> sources       = new List <string>();
            bool          needFilenames = (!this.generateInMemory) || this.writeSourceFiles;

            if (needFilenames)
            {
                string dirname = Path.GetFullPath(GeneratedSourceFolder);
                Directory.CreateDirectory(dirname);
            }
            referencedAssemblies = new Set <Assembly>();
            foreach (ITypeDeclaration td in typeDeclarations)
            {
                StringWriter    sw = new StringWriter();
                ILanguageWriter lw = new CSharpWriter() as ILanguageWriter;
                SourceNode      sn = lw.GenerateSource(td);
                LanguageWriter.WriteSourceNode(sw, sn);
                referencedAssemblies.AddRange(lw.ReferencedAssemblies);
                String sourceCode = sw.ToString();
                sources.Add(sourceCode);
                if (needFilenames)
                {
                    string filename = Path.GetFullPath(GetFilenameForType(GeneratedSourceFolder, td, ".cs"));
                    filenames.Add(filename);
                    if (writeSourceFiles)
                    {
                        if (useExistingFiles && File.Exists(filename))
                        {
                            if (showProgress)
                            {
                                Console.Write("Using existing source file: {0} ", filename);
                            }
                        }
                        else
                        {
                            if (showProgress)
                            {
                                Console.Write("Writing source file: {0} ", filename);
                            }
                            StreamWriter stw = new StreamWriter(filename);
                            stw.Write(sourceCode);
                            stw.Close();
                        }
                    }
                }
            }
            // sometimes we need to reference assemblies that are not directly referenced in the code,
            // as explained at: http://msdn.microsoft.com/en-us/library/yabyz3h4.aspx
            // If you reference an assembly (Assembly A) that references another assembly (Assembly B), you will need to reference Assembly B if:
            //   1. A type you use from Assembly A inherits from a type or implements an interface from Assembly B.
            //   2. You invoke a field, property, event, or method that has a return type or parameter type from Assembly B.
            // Rather than check for all this, we add references to all loaded assemblies referenced by referenced assemblies.
            Set <AssemblyName> loadedAssemblies = new Set <AssemblyName>(new AssemblyNameComparer());

            loadedAssemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().ListSelect(assembly => assembly.GetName()));
            Stack <Assembly> assemblyStack = new Stack <Assembly>();

            foreach (Assembly assembly in referencedAssemblies)
            {
                assemblyStack.Push(assembly);
            }
            while (assemblyStack.Count != 0)
            {
                Assembly assembly = assemblyStack.Pop();
                foreach (AssemblyName name in assembly.GetReferencedAssemblies())
                {
                    if (loadedAssemblies.Contains(name))
                    {
                        Assembly referenced = Assembly.Load(name);
                        if (!referencedAssemblies.Contains(referenced))
                        {
                            referencedAssemblies.Add(referenced);
                            assemblyStack.Push(referenced);
                        }
                    }
                }
            }
            if (showProgress)
            {
                watch.Stop();
                Console.WriteLine("({0}ms)", watch.ElapsedMilliseconds);
            }
            return(sources);
        }