コード例 #1
0
ファイル: Program-CodeGen.cs プロジェクト: xsharper/xsharper
        private static void doCodeGeneration(ScriptContext context, Script script)
        {
            if (!isCodeGeneration(context))
                return;

            context.Compiler.AddReference(null,typeof(System.Runtime.Remoting.Channels.Ipc.IpcChannel).Assembly.FullName,false,false,null);

            if (context.IsSet(xs.save) && script != null)
            {
                context.WriteLine(OutputType.Info, string.Format("Saving script to {0} ...", context[xs.save]));
                using (new ScriptContextScope(context))
                    script.Save(context.GetString(xs.save));
                context.WriteLine(OutputType.Info, string.Format("Script file {0} saved...", context[xs.save]));
            }

            if (context.IsSet(xs.genxsd))
            {
                context.WriteLine(OutputType.Info, string.Format("Generating XML schema  ..."));

                XmlSchema x = generateSchema(context);
                string sf = context.GetString(xs.genxsd);
                sf=Path.GetFullPath((sf == "*") ? x.Id + ".xsd" : sf);
                using (StreamWriter target = new StreamWriter(sf, false))
                    x.Write(target);

                context.WriteLine(OutputType.Info, string.Format("XML schema saved to {0} ...", sf));
            }

            // Generate source code
            StringWriter source = new StringWriter();
            string entryPoint = null;
            if (script != null && (context.IsSet(xs.genlibrary) || context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe) || context.IsSet(xs.gencs)))
            {
                context.WriteLine(OutputType.Info, "Generating C# source code...");
                SharpCodeGenerator codeGenerator = new SharpCodeGenerator(context.Compiler);

                if (context.IsSet(xs.@namespace))
                    codeGenerator.Namespace = context.GetString(xs.@namespace);

                string baseName = Path.GetFileNameWithoutExtension(script.Location).ToLower();
                if (script.Id!=null)
                    baseName = script.Id;
                baseName = Utils.FixFilename(baseName);

                if (context.IsSet(xs.@class))
                    codeGenerator.Class = context.GetString(xs.@class);
                else
                {
                    string cl;
                    cl = baseName;
                    if (char.IsDigit(cl[0]))
                        cl = "C" + cl;
                    if (!char.IsUpper(cl[0]))
                        cl = cl.Substring(0, 1).ToUpperInvariant() + cl.Substring(1);
                    cl = SharpCodeGenerator.ToValidName(cl);
                    if (cl == "Script" || cl == "Run")
                        cl = "C" + cl;
                    codeGenerator.Class = cl;
                }

                string pref = string.Empty;
                if (!string.IsNullOrEmpty(context.CodeOutputDirectory))
                    pref = Path.Combine(context.CodeOutputDirectory, "bin\\Debug\\");
                if (context.IsSet(xs.genexe) && context.GetString(xs.genexe) == "*")
                    context[xs.genexe] = pref+baseName + ".exe";
                if (context.IsSet(xs.genwinexe) && context.GetString(xs.genwinexe) == "*")
                    context[xs.genwinexe] = pref + baseName + ".exe";
                if (context.IsSet(xs.genlibrary) && context.GetString(xs.genlibrary) == "*")
                    context[xs.genlibrary] = pref + baseName + ".dll";
                if (context.IsSet(xs.gencs) && context.GetString(xs.gencs) == "*")
                    context[xs.gencs] = baseName + ".cs";

                GeneratorOptions options = GeneratorOptions.None;
                if (context.IsSet(xs.genexe))
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe | GeneratorOptions.CreateMain;
                if (context.IsSet(xs.genwinexe))
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe | GeneratorOptions.CreateMain | GeneratorOptions.WinExe;
                if (context.IsSet(xs.genlibrary))
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe;
                if (context.GetBool(xs.main, false))
                    options |= GeneratorOptions.CreateMain;
                if (context.GetBool(xs.forcenet20, false))
                    options |= GeneratorOptions.ForceNet20;
                if (context.CodeOutputDirectory == null && !context.IsSet(xs.gencs))
                    options |= GeneratorOptions.ForceNet20; // this is a bit faster
                if (context.GetBool(xs.noSrc, false))
                    options &= ~GeneratorOptions.IncludeSource;

                codeGenerator.Generate(context, source, script, options);
                if (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe))
                    entryPoint = codeGenerator.Namespace + "." + codeGenerator.Class + "Program";
            }

            // Save it to disk, if necessary
            string code = source.GetStringBuilder().ToString();
            if (script != null && context.IsSet(xs.gencs))
            {
                using (StreamWriter sourceDisk = new StreamWriter(context.GetString(xs.gencs), false))
                {
                    sourceDisk.Write(code);
                }
                context.WriteLine(OutputType.Info, string.Format("C# source code saved to {0} ...", context[xs.gencs]));

            }

            // Load the other part from resources
            if (script != null && (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe) || context.IsSet(xs.genlibrary)))
            {
                CompiledOutputType outType;
                string e;
                if (context.IsSet(xs.genexe))
                {
                    e = context.GetString(xs.genexe);
                    outType = CompiledOutputType.ConsoleExe;
                }
                else if (context.IsSet(xs.genwinexe))
                {
                    e = context.GetString(xs.genwinexe);
                    outType = CompiledOutputType.WindowsExe;
                }
                else
                {
                    e = context.GetString(xs.genlibrary);
                    outType = CompiledOutputType.Library;
                }

                context.WriteLine(OutputType.Info, string.Format("Compiling {0}...", e));

                var copt = new CompileOptions
                    {
                        ExtraOptions = context.GetString(xs.compilerOptions, null),
                        CodeOutputDirectory=context.CodeOutputDirectory,
                        StreamProvider=context.FindResourceMemoryStream,
                        FilesToEmbed = context.GetFilesToEmbed(),
                        EntryPoint=entryPoint,
                    };
                if (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe))
                {
                    if (script.RequireAdmin!=RequireAdminMode.User)
                    {
                        copt.Compiled = AppDomainLoader.TryLoadResourceStream(@"Manifests.requireAdministrator.res").ToArray();
                        copt.Manifest = AppDomainLoader.TryLoadResourceStream(@"Manifests.requireAdministrator.manifest").ToArray();
                    }
                    else
                    {
                        copt.Compiled = AppDomainLoader.TryLoadResourceStream(@"Manifests.asInvoker.res").ToArray();
                        copt.Manifest = AppDomainLoader.TryLoadResourceStream(@"Manifests.asInvoker.manifest").ToArray();
                    }
                    if (context.IsSet(xs.icon))
                        copt.Icon = context.ReadBytes(context.GetStr(xs.icon));
                    else
                        copt.Icon = AppDomainLoader.TryLoadResourceStream(@"Source.xsh.ico").ToArray();
                }

                // If we're building .EXE, add a reference to ZipLib. We don't want to do it
                // unnecessarily to save time, and also allow XSharper.Core use w/o ZipLib, so the reference is added only if it's loaded

                foreach (var ass in AppDomain.CurrentDomain.GetAssemblies())
                    if (ass.FullName != null && ass.FullName.Contains("ICSharpCode.SharpZipLib"))
                    {
                        context.Compiler.AddReference(null, ass.FullName, true, false,null);
                        break;
                    }

                context.Compiler.Compile(outType,code,e,copt);
                context.WriteLine(OutputType.Info, string.Format("Executable saved to {0} ...", e));
            }
        }
コード例 #2
0
ファイル: Program-CodeGen.cs プロジェクト: xsharper/xsharper
        private static void doCodeGeneration(ScriptContext context, Script script)
        {
            if (!isCodeGeneration(context))
            {
                return;
            }

            context.Compiler.AddReference(null, typeof(System.Runtime.Remoting.Channels.Ipc.IpcChannel).Assembly.FullName, false, false, null);

            if (context.IsSet(xs.save) && script != null)
            {
                context.WriteLine(OutputType.Info, string.Format("Saving script to {0} ...", context[xs.save]));
                using (new ScriptContextScope(context))
                    script.Save(context.GetString(xs.save));
                context.WriteLine(OutputType.Info, string.Format("Script file {0} saved...", context[xs.save]));
            }

            if (context.IsSet(xs.genxsd))
            {
                context.WriteLine(OutputType.Info, string.Format("Generating XML schema  ..."));

                XmlSchema x  = generateSchema(context);
                string    sf = context.GetString(xs.genxsd);
                sf = Path.GetFullPath((sf == "*") ? x.Id + ".xsd" : sf);
                using (StreamWriter target = new StreamWriter(sf, false))
                    x.Write(target);

                context.WriteLine(OutputType.Info, string.Format("XML schema saved to {0} ...", sf));
            }

            // Generate source code
            StringWriter source     = new StringWriter();
            string       entryPoint = null;

            if (script != null && (context.IsSet(xs.genlibrary) || context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe) || context.IsSet(xs.gencs)))
            {
                context.WriteLine(OutputType.Info, "Generating C# source code...");
                SharpCodeGenerator codeGenerator = new SharpCodeGenerator(context.Compiler);

                if (context.IsSet(xs.@namespace))
                {
                    codeGenerator.Namespace = context.GetString(xs.@namespace);
                }

                string baseName = Path.GetFileNameWithoutExtension(script.Location).ToLower();
                if (script.Id != null)
                {
                    baseName = script.Id;
                }
                baseName = Utils.FixFilename(baseName);

                if (context.IsSet(xs.@class))
                {
                    codeGenerator.Class = context.GetString(xs.@class);
                }
                else
                {
                    string cl;
                    cl = baseName;
                    if (char.IsDigit(cl[0]))
                    {
                        cl = "C" + cl;
                    }
                    if (!char.IsUpper(cl[0]))
                    {
                        cl = cl.Substring(0, 1).ToUpperInvariant() + cl.Substring(1);
                    }
                    cl = SharpCodeGenerator.ToValidName(cl);
                    if (cl == "Script" || cl == "Run")
                    {
                        cl = "C" + cl;
                    }
                    codeGenerator.Class = cl;
                }

                string pref = string.Empty;
                if (!string.IsNullOrEmpty(context.CodeOutputDirectory))
                {
                    pref = Path.Combine(context.CodeOutputDirectory, "bin\\Debug\\");
                }
                if (context.IsSet(xs.genexe) && context.GetString(xs.genexe) == "*")
                {
                    context[xs.genexe] = pref + baseName + ".exe";
                }
                if (context.IsSet(xs.genwinexe) && context.GetString(xs.genwinexe) == "*")
                {
                    context[xs.genwinexe] = pref + baseName + ".exe";
                }
                if (context.IsSet(xs.genlibrary) && context.GetString(xs.genlibrary) == "*")
                {
                    context[xs.genlibrary] = pref + baseName + ".dll";
                }
                if (context.IsSet(xs.gencs) && context.GetString(xs.gencs) == "*")
                {
                    context[xs.gencs] = baseName + ".cs";
                }

                GeneratorOptions options = GeneratorOptions.None;
                if (context.IsSet(xs.genexe))
                {
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe | GeneratorOptions.CreateMain;
                }
                if (context.IsSet(xs.genwinexe))
                {
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe | GeneratorOptions.CreateMain | GeneratorOptions.WinExe;
                }
                if (context.IsSet(xs.genlibrary))
                {
                    options |= GeneratorOptions.IncludeSource | GeneratorOptions.ForExe;
                }
                if (context.GetBool(xs.main, false))
                {
                    options |= GeneratorOptions.CreateMain;
                }
                if (context.GetBool(xs.forcenet20, false))
                {
                    options |= GeneratorOptions.ForceNet20;
                }
                if (context.CodeOutputDirectory == null && !context.IsSet(xs.gencs))
                {
                    options |= GeneratorOptions.ForceNet20; // this is a bit faster
                }
                if (context.GetBool(xs.noSrc, false))
                {
                    options &= ~GeneratorOptions.IncludeSource;
                }


                codeGenerator.Generate(context, source, script, options);
                if (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe))
                {
                    entryPoint = codeGenerator.Namespace + "." + codeGenerator.Class + "Program";
                }
            }

            // Save it to disk, if necessary
            string code = source.GetStringBuilder().ToString();

            if (script != null && context.IsSet(xs.gencs))
            {
                using (StreamWriter sourceDisk = new StreamWriter(context.GetString(xs.gencs), false))
                {
                    sourceDisk.Write(code);
                }
                context.WriteLine(OutputType.Info, string.Format("C# source code saved to {0} ...", context[xs.gencs]));
            }

            // Load the other part from resources
            if (script != null && (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe) || context.IsSet(xs.genlibrary)))
            {
                CompiledOutputType outType;
                string             e;
                if (context.IsSet(xs.genexe))
                {
                    e       = context.GetString(xs.genexe);
                    outType = CompiledOutputType.ConsoleExe;
                }
                else if (context.IsSet(xs.genwinexe))
                {
                    e       = context.GetString(xs.genwinexe);
                    outType = CompiledOutputType.WindowsExe;
                }
                else
                {
                    e       = context.GetString(xs.genlibrary);
                    outType = CompiledOutputType.Library;
                }

                context.WriteLine(OutputType.Info, string.Format("Compiling {0}...", e));


                var copt = new CompileOptions
                {
                    ExtraOptions        = context.GetString(xs.compilerOptions, null),
                    CodeOutputDirectory = context.CodeOutputDirectory,
                    StreamProvider      = context.FindResourceMemoryStream,
                    FilesToEmbed        = context.GetFilesToEmbed(),
                    EntryPoint          = entryPoint,
                };
                if (context.IsSet(xs.genexe) || context.IsSet(xs.genwinexe))
                {
                    if (script.RequireAdmin != RequireAdminMode.User)
                    {
                        copt.Compiled = AppDomainLoader.TryLoadResourceStream(@"Manifests.requireAdministrator.res").ToArray();
                        copt.Manifest = AppDomainLoader.TryLoadResourceStream(@"Manifests.requireAdministrator.manifest").ToArray();
                    }
                    else
                    {
                        copt.Compiled = AppDomainLoader.TryLoadResourceStream(@"Manifests.asInvoker.res").ToArray();
                        copt.Manifest = AppDomainLoader.TryLoadResourceStream(@"Manifests.asInvoker.manifest").ToArray();
                    }
                    if (context.IsSet(xs.icon))
                    {
                        copt.Icon = context.ReadBytes(context.GetStr(xs.icon));
                    }
                    else
                    {
                        copt.Icon = AppDomainLoader.TryLoadResourceStream(@"Source.xsh.ico").ToArray();
                    }
                }


                // If we're building .EXE, add a reference to ZipLib. We don't want to do it
                // unnecessarily to save time, and also allow XSharper.Core use w/o ZipLib, so the reference is added only if it's loaded

                foreach (var ass in AppDomain.CurrentDomain.GetAssemblies())
                {
                    if (ass.FullName != null && ass.FullName.Contains("ICSharpCode.SharpZipLib"))
                    {
                        context.Compiler.AddReference(null, ass.FullName, true, false, null);
                        break;
                    }
                }

                context.Compiler.Compile(outType, code, e, copt);
                context.WriteLine(OutputType.Info, string.Format("Executable saved to {0} ...", e));
            }
        }