Ejemplo n.º 1
0
        /// <summary>
        /// Compiles the file.
        /// </summary>
        /// <returns>The file.</returns>
        /// <param name="arguments">Arguments.</param>
        /// <param name="token">Token.</param>
        public override async Task <CodeCompilerResult> CompileFile(CodeCompilerArguments arguments, TextWriter log, CancellationToken token)
        {
            string       rspPath;
            StreamWriter rsp;

            if (arguments.TempDirectory != null)
            {
                rspPath = Path.Combine(arguments.TempDirectory, "response.rsp");
                rsp     = File.CreateText(rspPath);
            }
            else
            {
                rsp = CreateTempTextFile(".rsp", out rspPath);
            }

            using (rsp) {
                rsp.WriteLine("-target:library");

                if (arguments.Debug)
                {
                    rsp.WriteLine("-debug");
                }

                var langVersionArg = CSharpLangVersionHelper.GetLangVersionArg(arguments, runtime);
                if (langVersionArg != null)
                {
                    rsp.WriteLine(langVersionArg);
                }

                foreach (var reference in AssemblyResolver.GetResolvedReferences(runtime, arguments.AssemblyReferences))
                {
                    rsp.Write("-r:");
                    rsp.Write("\"");
                    rsp.Write(reference);
                    rsp.WriteLine("\"");
                }

                rsp.Write("-out:");
                rsp.Write("\"");
                rsp.Write(arguments.OutputPath);
                rsp.WriteLine("\"");

                if (arguments.AdditionalArguments != null)
                {
                    rsp.WriteLine(arguments.AdditionalArguments);
                }

                //in older versions of csc, these must come last
                foreach (var file in arguments.SourceFiles)
                {
                    rsp.Write("\"");
                    rsp.Write(file);
                    rsp.WriteLine("\"");
                }
            }

            var psi = new System.Diagnostics.ProcessStartInfo(runtime.CscPath)
            {
                Arguments              = $"-nologo -noconfig \"@{rspPath}\"",
                CreateNoWindow         = true,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                UseShellExecute        = false
            };

            if (log != null)
            {
                log.WriteLine($"{psi.FileName} {psi.Arguments}");
            }

            if (runtime.Kind == RuntimeKind.NetCore)
            {
                psi.Arguments = $"\"{psi.FileName}\" {psi.Arguments}";
                psi.FileName  = Path.GetFullPath(Path.Combine(runtime.RuntimeDir, "..", "..", "..", "dotnet"));
            }

            var stdout = new StringWriter();
            var stderr = new StringWriter();

            TextWriter outWriter = stderr, errWriter = stderr;

            if (log != null)
            {
                outWriter = new SplitOutputWriter(log, outWriter);
                errWriter = new SplitOutputWriter(log, errWriter);
            }

            var process = ProcessUtils.StartProcess(psi, outWriter, errWriter, token);

            var result = await process;

            var outputList = new List <string> ();
            var errors     = new List <CodeCompilerError> ();

            void ConsumeOutput(string s)
            {
                using (var sw = new StringReader(s)) {
                    string line;
                    while ((line = sw.ReadLine()) != null)
                    {
                        outputList.Add(line);
                        var err = MSBuildErrorParser.TryParseLine(line);
                        if (err != null)
                        {
                            errors.Add(err);
                        }
                    }
                }
            }

            ConsumeOutput(stdout.ToString());
            ConsumeOutput(stderr.ToString());

            if (log != null)
            {
                log.WriteLine($"{psi.FileName} {psi.Arguments}");
            }

            return(new CodeCompilerResult {
                Success = result == 0,
                Errors = errors,
                ExitCode = result,
                Output = outputList,
                ResponseFile = rspPath
            });
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Compiles the file.
        /// </summary>
        /// <returns>The file.</returns>
        /// <param name="arguments">Arguments.</param>
        /// <param name="token">Token.</param>
        public override async Task <CodeCompilerResult> CompileFile(CodeCompilerArguments arguments, TextWriter log, CancellationToken token)
        {
            var asmFileNames = new HashSet <string> (
                arguments.AssemblyReferences.Select(Path.GetFileName),
                StringComparer.OrdinalIgnoreCase
                );

            string       rspPath;
            StreamWriter rsp;

            if (arguments.TempDirectory != null)
            {
                rspPath = Path.Combine(arguments.TempDirectory, "response.rsp");
                rsp     = File.CreateText(rspPath);
            }
            else
            {
                rsp = CreateTempTextFile(".rsp", out rspPath);
            }

            using (rsp) {
                rsp.WriteLine("-target:library");

                if (arguments.Debug)
                {
                    rsp.WriteLine("-debug");
                }

                void AddIfNotPresent(string asm)
                {
                    if (!asmFileNames.Contains(asm))
                    {
                        rsp.Write("\"-r:");
                        rsp.Write(Path.Combine(runtime.RuntimeDir, asm));
                        rsp.WriteLine("\"");
                    }
                }

                AddIfNotPresent("mscorlib.dll");

                if (runtime.Kind == RuntimeKind.NetCore)
                {
                    AddIfNotPresent("netstandard.dll");
                    AddIfNotPresent("System.Runtime.dll");
                    //because we're referencing the impl not the ref asms, we end up
                    //having to ref internals
                    AddIfNotPresent("System.Private.CoreLib.dll");
                }

                foreach (var reference in arguments.AssemblyReferences)
                {
                    rsp.Write("-r:");
                    rsp.Write("\"");
                    rsp.Write(AssemblyResolver.Resolve(runtime, reference));
                    rsp.WriteLine("\"");
                }

                rsp.Write("-out:");
                rsp.Write("\"");
                rsp.Write(arguments.OutputPath);
                rsp.WriteLine("\"");

                //in older versions of csc, these must come last
                foreach (var file in arguments.SourceFiles)
                {
                    rsp.Write("\"");
                    rsp.Write(file);
                    rsp.WriteLine("\"");
                }
            }

            var psi = new System.Diagnostics.ProcessStartInfo(runtime.CscPath)
            {
                Arguments              = $"-nologo -noconfig \"@{rspPath}\" {arguments.AdditionalArguments}",
                CreateNoWindow         = true,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                UseShellExecute        = false
            };

            if (log != null)
            {
                log.WriteLine($"{psi.FileName} {psi.Arguments}");
            }

            if (runtime.Kind == RuntimeKind.NetCore)
            {
                psi.Arguments = $"\"{psi.FileName}\" {psi.Arguments}";
                psi.FileName  = Path.GetFullPath(Path.Combine(runtime.RuntimeDir, "..", "..", "..", "dotnet"));
            }

            var stdout = new StringWriter();
            var stderr = new StringWriter();

            TextWriter outWriter = stderr, errWriter = stderr;

            if (log != null)
            {
                outWriter = new SplitOutputWriter(log, outWriter);
                errWriter = new SplitOutputWriter(log, errWriter);
            }

            var process = ProcessUtils.StartProcess(psi, outWriter, errWriter, token);

            var result = await process;

            var outputList = new List <string> ();
            var errors     = new List <CodeCompilerError> ();

            void ConsumeOutput(string s)
            {
                using (var sw = new StringReader(s)) {
                    string line;
                    while ((line = sw.ReadLine()) != null)
                    {
                        outputList.Add(line);
                        var err = MSBuildErrorParser.TryParseLine(line);
                        if (err != null)
                        {
                            errors.Add(err);
                        }
                    }
                }
            }

            ConsumeOutput(stdout.ToString());
            ConsumeOutput(stderr.ToString());

            if (log != null)
            {
                log.WriteLine($"{psi.FileName} {psi.Arguments}");
            }

            return(new CodeCompilerResult {
                Success = result == 0,
                Errors = errors,
                ExitCode = result,
                Output = outputList,
                ResponseFile = rspPath
            });
        }