예제 #1
0
    public static unsafe int Main(string[] args)
    {
        string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
        string pluginDirectory;
        if (baseDirectory.EndsWith("bin"))
        {
            // Windows
            pluginDirectory = Path.GetFullPath(Path.Combine(baseDirectory, "..\\lib\\plugins"));
        }
        else
        {
            // *nix
            pluginDirectory = Path.Combine(baseDirectory, "plugins");
        }

        List<string> codeFiles = new List<string>();
        List<CodeCompileUnit> codeSnippets = new List<CodeCompileUnit>();
        List<Assembly> references = new List<Assembly>();
        List<string> imports = new List<string>();
        StringBuilder compilerOptions = new StringBuilder();
        bool codeOnly = false;
        string codeFile = string.Empty;
        string assemblyFile = "out.dll";
        int warnLevel = 0;
        string smokeLib = null;
        string defaultNamespace = "Qyoto";
        string globalClass = "Global";
        string destination = string.Empty;
        string docs = string.Empty;

        List<Assembly> plugins = new List<Assembly>();

        foreach (string arg in args)
        {
            if (arg == "-help" || arg == "--help" || arg == "-h")
            {
                PrintHelp();
                return 0;
            }
            if (arg == "-verbose")
            {
                Debug.Listeners.Add(new ConsoleTraceListener(true));
                continue;
            }
            if (arg == "-code-only")
            {
                codeOnly = true;
                continue;
            }
            if (arg.StartsWith("-code-file:"))
            {
                codeFile = arg.Substring(11);
                continue;
            }
            if (arg.StartsWith("-out:"))
            {
                assemblyFile = arg.Substring(5);
                continue;
            }
            if (arg.StartsWith("-warn:"))
            {
                warnLevel = int.Parse(arg.Substring(6));
                continue;
            }
            if (arg.StartsWith("-r:"))
            {
                references.Add(Assembly.LoadFrom(arg.Substring(3)));
                continue;
            }
            if (arg.StartsWith("-reference:"))
            {
                references.Add(Assembly.LoadFrom(arg.Substring(11)));
                continue;
            }
            if (arg.StartsWith("-global-class:"))
            {
                globalClass = arg.Substring(14);
                continue;
            }
            if (arg.StartsWith("-namespace:"))
            {
                defaultNamespace = arg.Substring(11);
                continue;
            }
            if (arg.StartsWith("-dest:"))
            {
                destination = arg.Substring("-dest:".Length);
                continue;
            }
            if (arg.StartsWith("-import:"))
            {
                imports.AddRange(arg.Substring(8).Split(','));
                continue;
            }
            if (arg.StartsWith("-docs:"))
            {
                docs = arg.Substring("-docs:".Length);
                continue;
            }
            if (arg.StartsWith("-plugins:"))
            {
                foreach (string str in arg.Substring(9).Split(','))
                {
                    Assembly a;
                    try
                    {
                        a = Assembly.LoadFrom(str);
                    }
                    catch (FileNotFoundException)
                    {
                        a = Assembly.LoadFrom(Path.Combine(pluginDirectory, str));
                    }
                    plugins.Add(a);
                }
                continue;
            }
            if (arg.StartsWith("-"))
            {
                compilerOptions.Append(" /");
                compilerOptions.Append(arg.Substring(1));
                continue;
            }

            if (smokeLib == null)
            {
                smokeLib = arg;
                continue;
            }

            codeFiles.Add(arg);
            FileStream fs = new FileStream(arg, FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            codeSnippets.Add(new CodeSnippetCompileUnit(sr.ReadToEnd()));
            sr.Close();
            fs.Close();
        }
        if (!string.IsNullOrEmpty(docs))
        {
            compilerOptions.Append(" /doc:" + Path.ChangeExtension(Path.GetFileName(assemblyFile), ".xml"));
        }

        compilerOptions.Append(" -debug");

        if (smokeLib == null)
        {
            PrintHelp();
            return 1;
        }

        Smoke* smoke = InitSmoke(smokeLib);
        if (smoke == (Smoke*) 0)
        {
            return SmokeLoadingFailure;
        }

        List<ICustomTranslator> customTranslators = (from plugin in plugins
                                                     from type in plugin.GetTypes()
                                                     from iface in type.GetInterfaces()
                                                     where iface == typeof(ICustomTranslator)
                                                     select (ICustomTranslator) Activator.CreateInstance(type)).ToList();

        GeneratorData data = new GeneratorData(smoke, defaultNamespace, imports, references, destination, docs);
        data.GlobalSpaceClassName = globalClass;
        Translator translator = new Translator(data, customTranslators);

        foreach (IHookProvider provider in from type in plugins.SelectMany(plugin => plugin.GetTypes())
                                           where type.GetInterfaces().Any(iface => iface == typeof(IHookProvider))
                                           select (IHookProvider) Activator.CreateInstance(type))
        {
            provider.Translator = translator;
            provider.Data = data;
            provider.RegisterHooks();
        }

        ClassesGenerator classgen = new ClassesGenerator(data, translator);
        Console.Error.WriteLine("Generating CodeCompileUnit...");
        classgen.Run();
        DestroySmoke((IntPtr) smoke);

        Dictionary<string, string> providerOptions = new Dictionary<string, string>();
        providerOptions.Add("CompilerVersion", "v4.0");
        CodeDomProvider csharp = new CSharpCodeProvider(providerOptions);
        if (codeFile != string.Empty)
        {
            FileStream fs = new FileStream(codeFile, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);

            Console.Error.WriteLine("Generating code...");
            CodeGeneratorOptions cgo = new CodeGeneratorOptions();
            csharp.GenerateCodeFromCompileUnit(data.CompileUnit, sw, cgo);
            sw.Close();
            fs.Close();
            codeFiles.Add(codeFile);
        }

        if (codeOnly)
        {
            if (codeFile == string.Empty)
            {
                Console.Error.WriteLine("Missing output filename. Use the -code-file:<file> option.");
                return MissingOptionError;
            }
            return NoError;
        }

        codeSnippets.Add(data.CompileUnit);

        Console.Error.WriteLine("Compiling assembly...");
        CompilerParameters cp = new CompilerParameters();
        cp.GenerateExecutable = false;
        cp.TreatWarningsAsErrors = false;
        cp.OutputAssembly = assemblyFile;
        cp.GenerateInMemory = false;
        cp.WarningLevel = warnLevel;
        cp.CompilerOptions = compilerOptions.ToString();
        cp.ReferencedAssemblies.Add(typeof(Regex).Assembly.Location);
        cp.ReferencedAssemblies.Add(typeof(ExtensionAttribute).Assembly.Location);
        foreach (Assembly assembly in references)
        {
            cp.ReferencedAssemblies.Add(assembly.Location);
        }
        CompilerResults cr;

        if(codeFile == null)
        {
            cr = csharp.CompileAssemblyFromDom(cp, codeSnippets.ToArray());
        }
        else
        {
            cr = csharp.CompileAssemblyFromFile(cp, codeFiles.ToArray());
        }

        bool errorsOccured = false;
        foreach (CompilerError error in cr.Errors)
        {
            if (!error.IsWarning)
                errorsOccured = true;
            Console.Error.WriteLine(error);
        }

        if (errorsOccured)
        {
            Console.Error.WriteLine("Errors occured. No assembly was generated.");
            return CompilationError;
        }
        Console.Error.WriteLine("Done.");
        return NoError;
    }
예제 #2
0
    public static unsafe int Main(string[] args)
    {
        string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
        string pluginDirectory;

        if (baseDirectory.EndsWith("bin"))
        {
            // Windows
            pluginDirectory = Path.GetFullPath(Path.Combine(baseDirectory, "..\\lib\\plugins"));
        }
        else
        {
            // *nix
            pluginDirectory = Path.Combine(baseDirectory, "plugins");
        }

        List <string>          codeFiles       = new List <string>();
        List <CodeCompileUnit> codeSnippets    = new List <CodeCompileUnit>();
        List <Assembly>        references      = new List <Assembly>();
        List <string>          imports         = new List <string>();
        StringBuilder          compilerOptions = new StringBuilder();
        bool   codeOnly         = false;
        string codeFile         = string.Empty;
        string assemblyFile     = "out.dll";
        int    warnLevel        = 0;
        string smokeLib         = null;
        string defaultNamespace = "Qyoto";
        string globalClass      = "Global";
        string destination      = string.Empty;
        string docs             = string.Empty;

        List <Assembly> plugins = new List <Assembly>();

        foreach (string arg in args)
        {
            if (arg == "-help" || arg == "--help" || arg == "-h")
            {
                PrintHelp();
                return(0);
            }
            if (arg == "-verbose")
            {
                Debug.Listeners.Add(new ConsoleTraceListener(true));
                continue;
            }
            if (arg == "-code-only")
            {
                codeOnly = true;
                continue;
            }
            if (arg.StartsWith("-code-file:"))
            {
                codeFile = arg.Substring(11);
                continue;
            }
            if (arg.StartsWith("-out:"))
            {
                assemblyFile = arg.Substring(5);
                continue;
            }
            if (arg.StartsWith("-warn:"))
            {
                warnLevel = int.Parse(arg.Substring(6));
                continue;
            }
            if (arg.StartsWith("-r:"))
            {
                references.Add(Assembly.LoadFrom(arg.Substring(3)));
                continue;
            }
            if (arg.StartsWith("-reference:"))
            {
                references.Add(Assembly.LoadFrom(arg.Substring(11)));
                continue;
            }
            if (arg.StartsWith("-global-class:"))
            {
                globalClass = arg.Substring(14);
                continue;
            }
            if (arg.StartsWith("-namespace:"))
            {
                defaultNamespace = arg.Substring(11);
                continue;
            }
            if (arg.StartsWith("-dest:"))
            {
                destination = arg.Substring("-dest:".Length);
                continue;
            }
            if (arg.StartsWith("-import:"))
            {
                imports.AddRange(arg.Substring(8).Split(','));
                continue;
            }
            if (arg.StartsWith("-docs:"))
            {
                docs = arg.Substring("-docs:".Length);
                continue;
            }
            if (arg.StartsWith("-plugins:"))
            {
                foreach (string str in arg.Substring(9).Split(','))
                {
                    Assembly a;
                    try
                    {
                        a = Assembly.LoadFrom(str);
                    }
                    catch (FileNotFoundException)
                    {
                        a = Assembly.LoadFrom(Path.Combine(pluginDirectory, str));
                    }
                    plugins.Add(a);
                }
                continue;
            }
            if (arg.StartsWith("-"))
            {
                compilerOptions.Append(" /");
                compilerOptions.Append(arg.Substring(1));
                continue;
            }

            if (smokeLib == null)
            {
                smokeLib = arg;
                continue;
            }

            codeFiles.Add(arg);
            FileStream   fs = new FileStream(arg, FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            codeSnippets.Add(new CodeSnippetCompileUnit(sr.ReadToEnd()));
            sr.Close();
            fs.Close();
        }
        if (!string.IsNullOrEmpty(docs))
        {
            compilerOptions.Append(" /doc:" + Path.ChangeExtension(Path.GetFileName(assemblyFile), ".xml"));
        }

        compilerOptions.Append(" -debug");

        if (smokeLib == null)
        {
            PrintHelp();
            return(1);
        }

        Smoke *smoke = InitSmoke(smokeLib);

        if (smoke == (Smoke *)0)
        {
            return(SmokeLoadingFailure);
        }

        List <ICustomTranslator> customTranslators = (from plugin in plugins
                                                      from type in plugin.GetTypes()
                                                      from iface in type.GetInterfaces()
                                                      where iface == typeof(ICustomTranslator)
                                                      select(ICustomTranslator) Activator.CreateInstance(type)).ToList();

        GeneratorData data = new GeneratorData(smoke, defaultNamespace, imports, references, destination, docs);

        data.GlobalSpaceClassName = globalClass;
        Translator translator = new Translator(data, customTranslators);

        foreach (IHookProvider provider in from type in plugins.SelectMany(plugin => plugin.GetTypes())
                 where type.GetInterfaces().Any(iface => iface == typeof(IHookProvider))
                 select(IHookProvider) Activator.CreateInstance(type))
        {
            provider.Translator = translator;
            provider.Data       = data;
            provider.RegisterHooks();
        }

        ClassesGenerator classgen = new ClassesGenerator(data, translator);

        Console.Error.WriteLine("Generating CodeCompileUnit...");
        classgen.Run();
        DestroySmoke((IntPtr)smoke);

        Dictionary <string, string> providerOptions = new Dictionary <string, string>();

        providerOptions.Add("CompilerVersion", "v4.0");
        CodeDomProvider csharp = new CSharpCodeProvider(providerOptions);

        if (codeFile != string.Empty)
        {
            FileStream   fs = new FileStream(codeFile, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);

            Console.Error.WriteLine("Generating code...");
            CodeGeneratorOptions cgo = new CodeGeneratorOptions();
            csharp.GenerateCodeFromCompileUnit(data.CompileUnit, sw, cgo);
            sw.Close();
            fs.Close();
            codeFiles.Add(codeFile);
        }

        if (codeOnly)
        {
            if (codeFile == string.Empty)
            {
                Console.Error.WriteLine("Missing output filename. Use the -code-file:<file> option.");
                return(MissingOptionError);
            }
            return(NoError);
        }

        codeSnippets.Add(data.CompileUnit);

        Console.Error.WriteLine("Compiling assembly...");
        CompilerParameters cp = new CompilerParameters();

        cp.GenerateExecutable    = false;
        cp.TreatWarningsAsErrors = false;
        cp.OutputAssembly        = assemblyFile;
        cp.GenerateInMemory      = false;
        cp.WarningLevel          = warnLevel;
        cp.CompilerOptions       = compilerOptions.ToString();
        cp.ReferencedAssemblies.Add(typeof(Regex).Assembly.Location);
        cp.ReferencedAssemblies.Add(typeof(ExtensionAttribute).Assembly.Location);
        foreach (Assembly assembly in references)
        {
            cp.ReferencedAssemblies.Add(assembly.Location);
        }
        CompilerResults cr;

        if (codeFile == null)
        {
            cr = csharp.CompileAssemblyFromDom(cp, codeSnippets.ToArray());
        }
        else
        {
            cr = csharp.CompileAssemblyFromFile(cp, codeFiles.ToArray());
        }

        bool errorsOccured = false;

        foreach (CompilerError error in cr.Errors)
        {
            if (!error.IsWarning)
            {
                errorsOccured = true;
            }
            Console.Error.WriteLine(error);
        }

        if (errorsOccured)
        {
            Console.Error.WriteLine("Errors occured. No assembly was generated.");
            return(CompilationError);
        }
        Console.Error.WriteLine("Done.");
        return(NoError);
    }