public void TrivialSourceFileOnlyCsc()
        {
            var hello = Temp.CreateFile().WriteAllText(helloWorldCS).Path;
            var touchedDir = Temp.CreateDirectory();
            var touchedBase = Path.Combine(touchedDir.Path, "touched");

            var cmd = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", hello,
               string.Format(@"/touchedfiles:""{0}""", touchedBase) });
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);

            List<string> expectedReads;
            List<string> expectedWrites;
            BuildTouchedFiles(cmd,
                              Path.ChangeExtension(hello, "exe"),
                              out expectedReads,
                              out expectedWrites);
            var exitCode = cmd.Run(outWriter);

            Assert.Equal("", outWriter.ToString().Trim());
            Assert.Equal(0, exitCode);
            AssertTouchedFilesEqual(expectedReads,
                                    expectedWrites,
                                    touchedBase);

            CleanupAllGeneratedFiles(hello);
        }
        public void NoDiagnostics()
        {
            var helloWorldCS = @"using System;

class C
{
    public static void Main(string[] args)
    {
        Console.WriteLine(""Hello, world"");
    }
}";
            var hello = Temp.CreateFile().WriteAllText(helloWorldCS).Path;
            var errorLogDir = Temp.CreateDirectory();
            var errorLogFile = Path.Combine(errorLogDir.Path, "ErrorLog.txt");

            var cmd = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", hello,
               $"/errorlog:{errorLogFile}" });
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);

            var exitCode = cmd.Run(outWriter);

            Assert.Equal("", outWriter.ToString().Trim());
            Assert.Equal(0, exitCode);

            var actualOutput = File.ReadAllText(errorLogFile).Trim();

            var expectedHeader = GetExpectedErrorLogHeader(actualOutput, cmd);
            var expectedIssues = @"
      ""issues"": [
      ]
    }
  ]
}";
            var expectedText = expectedHeader + expectedIssues;
            Assert.Equal(expectedText, actualOutput);

            CleanupAllGeneratedFiles(hello);
            CleanupAllGeneratedFiles(errorLogFile);
        }
        private static string VerifyOutput(TempDirectory sourceDir, TempFile sourceFile,
                                           bool includeCurrentAssemblyAsAnalyzerReference = true,
                                           string[] additionalFlags = null,
                                           int expectedInfoCount = 0,
                                           int expectedWarningCount = 0,
                                           int expectedErrorCount = 0)
        {
            var args = new[] {
                                "/nologo", "/preferreduilang:en", "/t:library",
                                sourceFile.Path
                             };
            if (includeCurrentAssemblyAsAnalyzerReference)
            {
                args = args.Append("/a:" + Assembly.GetExecutingAssembly().Location);
            }
            if (additionalFlags != null)
            {
                args = args.Append(additionalFlags);
            }

            var csc = new MockCSharpCompiler(null, sourceDir.Path, args);
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var exitCode = csc.Run(outWriter);
            var output = outWriter.ToString();

            var expectedExitCode = expectedErrorCount > 0 ? 1 : 0;
            Assert.True(
                expectedExitCode == exitCode,
                string.Format("Expected exit code to be '{0}' was '{1}'.{2} Output:{3}{4}",
                expectedExitCode, exitCode, Environment.NewLine, Environment.NewLine, output));

            Assert.DoesNotContain("hidden", output, StringComparison.Ordinal);

            if (expectedInfoCount == 0)
            {
                Assert.DoesNotContain("info", output, StringComparison.Ordinal);
            }
            else
            {
                Assert.Equal(expectedInfoCount, OccurrenceCount(output, "info"));
            }

            if (expectedWarningCount == 0)
            {
                Assert.DoesNotContain("warning", output, StringComparison.Ordinal);
            }
            else
            {
                Assert.Equal(expectedWarningCount, OccurrenceCount(output, "warning"));
            }

            if (expectedErrorCount == 0)
            {
                Assert.DoesNotContain("error", output, StringComparison.Ordinal);
            }
            else
            {
                Assert.Equal(expectedErrorCount, OccurrenceCount(output, "error"));
            }

            return output;
        }
        public void NoInfoDiagnostics()
        {
            string filePath = Temp.CreateFile().WriteAllText(@"
using System.Diagnostics; // Unused.
").Path;
            var cmd = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/target:library", filePath });
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var exitCode = cmd.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Equal("", outWriter.ToString().Trim());

            CleanupAllGeneratedFiles(filePath);
        }
        public void AnalyzerExceptionDiagnosticCanBeConfigured()
        {
            var srcFile = Temp.CreateFile().WriteAllText(@"class C {}");
            var srcDirectory = Path.GetDirectoryName(srcFile.Path);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, _baseDirectory, new[] { "/t:library", $"/warnaserror:{AnalyzerExecutor.AnalyzerExceptionDiagnosticId}", srcFile.Path },
               analyzer: new AnalyzerThatThrowsInGetMessage());

            var exitCode = csc.Run(outWriter);
            Assert.NotEqual(0, exitCode);
            var output = outWriter.ToString();

            // Verify that the analyzer exception diagnostic for the exception throw in AnalyzerThatThrowsInGetMessage is also reported.
            Assert.Contains(AnalyzerExecutor.AnalyzerExceptionDiagnosticId, output, StringComparison.Ordinal);
            Assert.Contains(nameof(NotImplementedException), output, StringComparison.Ordinal);

            CleanupAllGeneratedFiles(srcFile.Path);
        }
        public void WriteXml()
        {
            var source = @"
/// <summary>
/// A subtype of <see cref=""object""/>.
/// </summary>
public class C { }
";

            var sourcePath = Temp.CreateFile(directory: _baseDirectory, extension: ".cs").WriteAllText(source).Path;
            string xmlPath = Path.Combine(_baseDirectory, "Test.xml");
            var csc = new MockCSharpCompiler(null, _baseDirectory, new[] { "/target:library", "/out:Test.dll", "/doc:" + xmlPath, sourcePath });

            var writer = new StringWriter(CultureInfo.InvariantCulture);
            var exitCode = csc.Run(writer);
            if (exitCode != 0)
            {
                Console.WriteLine(writer.ToString());
                Assert.Equal(0, exitCode);
            }

            var bytes = File.ReadAllBytes(xmlPath);
            var actual = new string(Encoding.UTF8.GetChars(bytes));
            var expected = @"
<?xml version=""1.0""?>
<doc>
    <assembly>
        <name>Test</name>
    </assembly>
    <members>
        <member name=""T:C"">
            <summary>
            A subtype of <see cref=""T:System.Object""/>.
            </summary>
        </member>
    </members>
</doc>
";
            Assert.Equal(expected.Trim(), actual.Trim());

            System.IO.File.Delete(xmlPath);
            System.IO.File.Delete(sourcePath);

            CleanupAllGeneratedFiles(sourcePath);
            CleanupAllGeneratedFiles(xmlPath);
        }
        public void IOFailure_OpenPdbFileNotCalled()
        {
            string sourcePath = MakeTrivialExe();
            string exePath = Path.Combine(Path.GetDirectoryName(sourcePath), "test.exe");
            string pdbPath = Path.ChangeExtension(exePath, ".pdb");
            var csc = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/debug-", $"/out:{exePath}", sourcePath });
            csc.FileOpen = (file, mode, access, share) =>
            {
                if (file == pdbPath)
                {
                    throw new IOException();
                }

                return File.Open(file, (FileMode)mode, (FileAccess)access, (FileShare)share);
            };

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            Assert.Equal(0, csc.Run(outWriter));

            System.IO.File.Delete(sourcePath);
            System.IO.File.Delete(exePath);
            System.IO.File.Delete(pdbPath);
            CleanupAllGeneratedFiles(sourcePath);
        }
        public void CheckFullpaths()
        {
            string source = Temp.CreateFile(prefix: "", extension: ".cs").WriteAllText(@"
public class C
{
    public static void Main()
    {
        string x;
    }
}").Path;

            var baseDir = Path.GetDirectoryName(source);
            var fileName = Path.GetFileName(source);

            // Checks the base case without /fullpaths (expect to see relative path name)
            //      c:\temp> csc.exe c:\temp\a.cs
            //      a.cs(6,16): warning CS0168: The variable 'x' is declared but never used
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, baseDir, new[] { source, "/preferreduilang:en" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains(fileName + "(6,16): warning CS0168: The variable 'x' is declared but never used", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the base case without /fullpaths when the file is located in the sub-folder (expect to see relative path name)
            //      c:\temp> csc.exe c:\temp\example\a.cs
            //      example\a.cs(6,16): warning CS0168: The variable 'x' is declared but never used
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(null, Directory.GetParent(baseDir).FullName, new[] { source, "/preferreduilang:en" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains(fileName + "(6,16): warning CS0168: The variable 'x' is declared but never used", outWriter.ToString(), StringComparison.Ordinal);
            Assert.DoesNotContain(source, outWriter.ToString(), StringComparison.Ordinal);

            // Checks the base case without /fullpaths when the file is not located under the base directory (expect to see the full path name)
            //      c:\temp> csc.exe c:\test\a.cs
            //      c:\test\a.cs(6,16): warning CS0168: The variable 'x' is declared but never used
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(null, Temp.CreateDirectory().Path, new[] { source, "/preferreduilang:en" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains(source + "(6,16): warning CS0168: The variable 'x' is declared but never used", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the case with /fullpaths (expect to see the full paths)
            //      c:\temp> csc.exe c:\temp\a.cs /fullpaths
            //      c:\temp\a.cs(6,16): warning CS0168: The variable 'x' is declared but never used
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(null, baseDir, new[] { source, "/fullpaths", "/preferreduilang:en" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains(source + @"(6,16): warning CS0168: The variable 'x' is declared but never used", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the base case without /fullpaths when the file is located in the sub-folder (expect to see the full path name)
            //      c:\temp> csc.exe c:\temp\example\a.cs /fullpaths
            //      c:\temp\example\a.cs(6,16): warning CS0168: The variable 'x' is declared but never used
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(null, Directory.GetParent(baseDir).FullName, new[] { source, "/preferreduilang:en", "/fullpaths" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains(source + "(6,16): warning CS0168: The variable 'x' is declared but never used", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the base case without /fullpaths when the file is not located under the base directory (expect to see the full path name)
            //      c:\temp> csc.exe c:\test\a.cs /fullpaths
            //      c:\test\a.cs(6,16): warning CS0168: The variable 'x' is declared but never used
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(null, Temp.CreateDirectory().Path, new[] { source, "/preferreduilang:en", "/fullpaths" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains(source + "(6,16): warning CS0168: The variable 'x' is declared but never used", outWriter.ToString(), StringComparison.Ordinal);

            CleanupAllGeneratedFiles(source);
        }
        public void NoLogo_1()
        {
            string source = @"
class C
{
}
";
            var dir = Temp.CreateDirectory();

            var file = dir.CreateFile("a.cs");
            file.WriteAllText(source);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { "/nologo", "/target:library", "a.cs" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Equal(@"",
                outWriter.ToString().Trim());

            CleanupAllGeneratedFiles(file.Path);
        }
        public void VerifyDiagnosticSeverityNotLocalized()
        {
            string source = @"
class C
{
}
";
            var dir = Temp.CreateDirectory();

            var file = dir.CreateFile("a.cs");
            file.WriteAllText(source);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { "/nologo", "/target:exe", "a.cs" });
            int exitCode = csc.Run(outWriter);
            Assert.NotEqual(0, exitCode);

            // If "error" was localized, below assert will fail on PLOC builds. The output would be something like: "!pTCvB!vbc : !FLxft!error 表! CS5001:"
            Assert.Contains("error CS5001:", outWriter.ToString().Trim());

            CleanupAllGeneratedFiles(file.Path);
        }
        public void OutputFileName_NoEntryPoint()
        {
            string source = @"
class C
{
}
";
            var dir = Temp.CreateDirectory();

            var file = dir.CreateFile("a.cs");
            file.WriteAllText(source);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { "/nologo", "/preferreduilang:en", "/target:exe", "a.cs" });
            int exitCode = csc.Run(outWriter);
            Assert.NotEqual(0, exitCode);
            Assert.Equal("error CS5001: Program does not contain a static 'Main' method suitable for an entry point", outWriter.ToString().Trim());

            CleanupAllGeneratedFiles(file.Path);
        }
        public void QuotedDefineInRespFileErr()
        {
            string source = Temp.CreateFile("a.cs").WriteAllText(@"
#if NN
class myClass
{
#endif
    static int Main()
#if DD
    {
        return 1;
#endif

#if AA
    }
#endif

#if BB
}
#endif

").Path;

            string rsp = Temp.CreateFile().WriteAllText(@"
/d:""DD""""
/d:""AA;BB""
/d:""N"" ""N
").Path;

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            // csc errors_whitespace_008.cs @errors_whitespace_008.cs.rsp 
            var csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/preferreduilang:en" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(1, exitCode);

            CleanupAllGeneratedFiles(source);
            CleanupAllGeneratedFiles(rsp);
        }
        public void ResponseFilesWithEmptyAliasReference2()
        {
            string source = Temp.CreateFile("a.cs").WriteAllText(@"
// <Area> ExternAlias - command line alias</Area>
// <Title> 
// negative test cases: empty file name ("""")
// </Title>
// <Description>
// </Description>
// <RelatedBugs></RelatedBugs> 

//<Expects Status=error>CS1680:.*myAlias=</Expects>

// <Code> 
class myClass
{
    static int Main()
    {
        return 1;
    }
}
// </Code>
").Path;

            string rsp = Temp.CreateFile().WriteAllText(@"
/nologo
/r:myAlias=""  ""
").Path;

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            // csc errors_whitespace_008.cs @errors_whitespace_008.cs.rsp 
            var csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/preferreduilang:en" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(1, exitCode);
            Assert.Equal("error CS1680: Invalid reference alias option: 'myAlias=' -- missing filename", outWriter.ToString().Trim());

            CleanupAllGeneratedFiles(source);
            CleanupAllGeneratedFiles(rsp);
        }
        public void BinaryFileErrorTest()
        {
            var binaryPath = Temp.CreateFile().WriteAllBytes(TestResources.NetFX.v4_0_30319.mscorlib).Path;
            var csc = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", binaryPath });
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            int exitCode = csc.Run(outWriter);
            Assert.Equal(1, exitCode);
            Assert.Equal(
                "error CS2015: '" + binaryPath + "' is a binary file instead of a text file",
                outWriter.ToString().Trim());

            CleanupAllGeneratedFiles(binaryPath);
        }
        public void ModuleName001()
        {
            var dir = Temp.CreateDirectory();

            var file1 = dir.CreateFile("a.cs");
            file1.WriteAllText(@"
                    class c1
                    {
                        public static void Main(){}
                    }
                ");

            var exeName = "aa.exe";
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { "/modulename:hocusPocus ", "/out:" + exeName + " ", file1.Path });
            int exitCode = csc.Run(outWriter);
            if (exitCode != 0)
            {
                Console.WriteLine(outWriter.ToString());
                Assert.Equal(0, exitCode);
            }


            Assert.Equal(1, Directory.EnumerateFiles(dir.Path, exeName).Count());

            using (var metadata = ModuleMetadata.CreateFromImage(File.ReadAllBytes(Path.Combine(dir.Path, "aa.exe"))))
            {
                var peReader = metadata.Module.GetMetadataReader();

                Assert.True(peReader.IsAssembly);

                Assert.Equal("aa", peReader.GetString(peReader.GetAssemblyDefinition().Name));
                Assert.Equal("hocusPocus", peReader.GetString(peReader.GetModuleDefinition().Name));
            }

            if (System.IO.File.Exists(exeName))
            {
                System.IO.File.Delete(exeName);
            }

            CleanupAllGeneratedFiles(file1.Path);
        }
        public void ResponseFilesWithNoconfig_01()
        {
            string source = Temp.CreateFile("a.cs").WriteAllText(@"
public class C
{
    public static void Main()
    {
        int x; // CS0168
    }
}").Path;

            string rsp = Temp.CreateFile().WriteAllText(@"
/warnaserror
").Path;
            // Checks the base case without /noconfig (expect to see error)
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/preferreduilang:en" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(1, exitCode);
            Assert.Contains("error CS0168: The variable 'x' is declared but never used\r\n", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the case with /noconfig (expect to see warning, instead of error)
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/noconfig", "/preferreduilang:en" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains("warning CS0168: The variable 'x' is declared but never used\r\n", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the case with /NOCONFIG (expect to see warning, instead of error)
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/NOCONFIG", "/preferreduilang:en" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains("warning CS0168: The variable 'x' is declared but never used\r\n", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the case with -noconfig (expect to see warning, instead of error)
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "-noconfig", "/preferreduilang:en" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains("warning CS0168: The variable 'x' is declared but never used\r\n", outWriter.ToString(), StringComparison.Ordinal);

            CleanupAllGeneratedFiles(source);
            CleanupAllGeneratedFiles(rsp);
        }
        public void ResponseFilesWithNoconfig_04()
        {
            string source = Temp.CreateFile("a.cs").WriteAllText(@"
public class C
{
    public static void Main()
    {
    }
}").Path;

            string rsp = Temp.CreateFile().WriteAllText(@"
-noconfig
").Path;
            // Checks the case with /noconfig inside the response file (expect to see warning)
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/preferreduilang:en" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains("warning CS2023: Ignoring /noconfig option because it was specified in a response file\r\n", outWriter.ToString(), StringComparison.Ordinal);

            // Checks the case with -noconfig inside the response file as along with /nowarn (expect to see warning)
            // to verify that this warning is not suppressed by the /nowarn option (See MSDN).
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/preferreduilang:en", "/nowarn:2023" });
            exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Contains("warning CS2023: Ignoring /noconfig option because it was specified in a response file\r\n", outWriter.ToString(), StringComparison.Ordinal);

            CleanupAllGeneratedFiles(source);
            CleanupAllGeneratedFiles(rsp);
        }
        public void NoLogo_2()
        {
            string source = @"
class C
{
}
";
            var dir = Temp.CreateDirectory();

            var file = dir.CreateFile("a.cs");
            file.WriteAllText(source);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { "/target:library", "/preferreduilang:en", "a.cs" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Equal(@"
Microsoft (R) Visual C# Compiler version A.B.C.D
Copyright (C) Microsoft Corporation. All rights reserved.".Trim(),
                Regex.Replace(outWriter.ToString().Trim(), "version \\d+\\.\\d+\\.\\d+(\\.\\d+)?", "version A.B.C.D"));
            // Privately queued builds have 3-part version numbers instead of 4.  Since we're throwing away the version number,
            // making the last part optional will fix this.

            CleanupAllGeneratedFiles(file.Path);
        }
        public void IOFailure_OpenOutputFile()
        {
            string sourcePath = MakeTrivialExe();
            string exePath = Path.Combine(Path.GetDirectoryName(sourcePath), "test.exe");
            var csc = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", $"/out:{exePath}", sourcePath });
            csc.FileOpen = (file, mode, access, share) =>
            {
                if (file == exePath)
                {
                    throw new IOException();
                }

                return File.Open(file, (FileMode)mode, (FileAccess)access, (FileShare)share);
            };

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            Assert.Equal(1, csc.Run(outWriter));
            Assert.Contains($"error CS2012: Cannot open '{exePath}' for writing", outWriter.ToString());

            System.IO.File.Delete(sourcePath);
            System.IO.File.Delete(exePath);
            CleanupAllGeneratedFiles(sourcePath);
        }
        private void CheckOutputFileName(string source1, string source2, string inputName1, string inputName2, string[] commandLineArguments, string expectedOutputName)
        {
            var dir = Temp.CreateDirectory();

            var file1 = dir.CreateFile(inputName1);
            file1.WriteAllText(source1);

            var file2 = dir.CreateFile(inputName2);
            file2.WriteAllText(source2);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, commandLineArguments.Concat(new[] { inputName1, inputName2 }).ToArray());
            int exitCode = csc.Run(outWriter);
            if (exitCode != 0)
            {
                Console.WriteLine(outWriter.ToString());
                Assert.Equal(0, exitCode);
            }

            Assert.Equal(1, Directory.EnumerateFiles(dir.Path, "*" + PathUtilities.GetExtension(expectedOutputName)).Count());
            Assert.Equal(1, Directory.EnumerateFiles(dir.Path, expectedOutputName).Count());

            using (var metadata = ModuleMetadata.CreateFromImage(File.ReadAllBytes(Path.Combine(dir.Path, expectedOutputName))))
            {
                var peReader = metadata.Module.GetMetadataReader();

                Assert.True(peReader.IsAssembly);

                Assert.Equal(PathUtilities.RemoveExtension(expectedOutputName), peReader.GetString(peReader.GetAssemblyDefinition().Name));
                Assert.Equal(expectedOutputName, peReader.GetString(peReader.GetModuleDefinition().Name));
            }

            if (System.IO.File.Exists(expectedOutputName))
            {
                System.IO.File.Delete(expectedOutputName);
            }

            CleanupAllGeneratedFiles(file1.Path);
            CleanupAllGeneratedFiles(file2.Path);
        }
        public void IOFailure_OpenXmlFinal()
        {
            string sourcePath = MakeTrivialExe();
            string xmlPath = Path.Combine(_baseDirectory, "Test.xml");
            var csc = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/doc:" + xmlPath, sourcePath });
            csc.FileOpen = (file, mode, access, share) =>
            {
                if (file == xmlPath)
                {
                    throw new IOException();
                }
                else
                {
                    return File.Open(file, (FileMode)mode, (FileAccess)access, (FileShare)share);
                }
            };

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            int exitCode = csc.Run(outWriter);

            var expectedOutput = string.Format("error CS0016: Could not write to output file '{0}' -- 'I/O error occurred.'", xmlPath);
            Assert.Equal(expectedOutput, outWriter.ToString().Trim());

            Assert.NotEqual(0, exitCode);

            System.IO.File.Delete(xmlPath);
            System.IO.File.Delete(sourcePath);
            CleanupAllGeneratedFiles(sourcePath);
        }
        public void MissingReference()
        {
            string source = @"
class C
{
}
";
            var dir = Temp.CreateDirectory();

            var file = dir.CreateFile("a.cs");
            file.WriteAllText(source);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { "/nologo", "/preferreduilang:en", "/r:missing.dll", "a.cs" });
            int exitCode = csc.Run(outWriter);
            Assert.Equal(1, exitCode);
            Assert.Equal("error CS0006: Metadata file 'missing.dll' could not be found", outWriter.ToString().Trim());

            CleanupAllGeneratedFiles(file.Path);
        }
        public void ReportAnalyzerOutput()
        {
            var srcFile = Temp.CreateFile().WriteAllText(@"class C {}");
            var srcDirectory = Path.GetDirectoryName(srcFile.Path);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, srcDirectory, new[] { "/reportanalyzer", "/t:library", "/a:" + Assembly.GetExecutingAssembly().Location, srcFile.Path });
            var exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            var output = outWriter.ToString();
            Assert.Contains(CodeAnalysisResources.AnalyzerExecutionTimeColumnHeader, output, StringComparison.Ordinal);
            Assert.Contains(new WarningDiagnosticAnalyzer().ToString(), output, StringComparison.Ordinal);
            CleanupAllGeneratedFiles(srcFile.Path);
        }
        private int GetExitCode(string source, string fileName, string[] commandLineArguments)
        {
            var dir = Temp.CreateDirectory();
            var file = dir.CreateFile(fileName);
            file.WriteAllText(source);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, commandLineArguments.Concat(new[] { fileName }).ToArray());
            int exitCode = csc.Run(outWriter);

            return exitCode;
        }
        public void AnalyzerReportsMisformattedDiagnostic()
        {
            var srcFile = Temp.CreateFile().WriteAllText(@"class C {}");
            var srcDirectory = Path.GetDirectoryName(srcFile.Path);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, _baseDirectory, new[] { "/t:library", srcFile.Path },
               analyzer: new AnalyzerReportingMisformattedDiagnostic());

            var exitCode = csc.Run(outWriter);
            Assert.Equal(0, exitCode);
            var output = outWriter.ToString();

            // Verify that the diagnostic reported by AnalyzerReportingMisformattedDiagnostic is reported with the message format string, instead of the formatted message.
            Assert.Contains(AnalyzerThatThrowsInGetMessage.Rule.Id, output, StringComparison.Ordinal);
            Assert.Contains(AnalyzerThatThrowsInGetMessage.Rule.MessageFormat.ToString(CultureInfo.InvariantCulture), output, StringComparison.Ordinal);

            CleanupAllGeneratedFiles(srcFile.Path);
        }
        public void CompilationWithNonExistingOutPath()
        {
            string source = @"
public class C
{
    public static void Main()
    {
    }
}";

            var fileName = "a.cs";
            var dir = Temp.CreateDirectory();
            var file = dir.CreateFile(fileName);
            file.WriteAllText(source);
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { fileName, "/preferreduilang:en", "/target:exe", "/out:sub\\a.exe" });
            int exitCode = csc.Run(outWriter);

            Assert.Equal(1, exitCode);
            Assert.Contains("error CS2012: Cannot open '" + dir.Path + "\\sub\\a.exe' for writing", outWriter.ToString(), StringComparison.Ordinal);

            CleanupAllGeneratedFiles(file.Path);
        }
        public void ReservedDeviceNameAsFileName2()
        {
            string filePath = Temp.CreateFile().WriteAllText(@"class C {}").Path;
            // make sure reserved device names don't 
            var cmd = new MockCSharpCompiler(null, _baseDirectory, new[] { "/r:com2.dll", "/target:library", "/preferreduilang:en", filePath });
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var exitCode = cmd.Run(outWriter);
            Assert.Equal(1, exitCode);
            Assert.Contains("error CS0006: Metadata file 'com2.dll' could not be found", outWriter.ToString(), StringComparison.Ordinal);

            cmd = new MockCSharpCompiler(null, _baseDirectory, new[] { "/link:..\\lpt8.dll", "/target:library", "/preferreduilang:en", filePath });
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            exitCode = cmd.Run(outWriter);
            Assert.Equal(1, exitCode);
            Assert.Contains("error CS0006: Metadata file '..\\lpt8.dll' could not be found", outWriter.ToString(), StringComparison.Ordinal);

            cmd = new MockCSharpCompiler(null, _baseDirectory, new[] { "/lib:aux", "/preferreduilang:en", filePath });
            outWriter = new StringWriter(CultureInfo.InvariantCulture);
            exitCode = cmd.Run(outWriter);
            Assert.Equal(1, exitCode);
            Assert.Contains("warning CS1668: Invalid search path 'aux' specified in '/LIB option' -- 'directory does not exist'", outWriter.ToString(), StringComparison.Ordinal);

            CleanupAllGeneratedFiles(filePath);
        }
        public void CompilationWithWrongOutPath_03()
        {
            string source = @"
public class C
{
    public static void Main()
    {
    }
}";

            var fileName = "a.cs";
            var dir = Temp.CreateDirectory();
            var file = dir.CreateFile(fileName);
            file.WriteAllText(source);
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { fileName, "/preferreduilang:en", "/target:exe", "/out:aaa:\\a.exe" });
            int exitCode = csc.Run(outWriter);

            Assert.Equal(1, exitCode);
            Assert.Contains(@"error CS2021: File name 'aaa:\a.exe' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long", outWriter.ToString(), StringComparison.Ordinal);

            CleanupAllGeneratedFiles(file.Path);
        }
        public void CompileShiftJisOnShiftJis()
        {
            var dir = Temp.CreateDirectory();
            var src = dir.CreateFile("sjis.cs").WriteAllBytes(TestResources.General.ShiftJisSource);

            var cmd = new MockCSharpCompiler(null, dir.Path, new[] { "/nologo", src.Path });

            Assert.Null(cmd.Arguments.Encoding);

            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var exitCode = cmd.Run(outWriter);
            Assert.Equal(0, exitCode);
            Assert.Equal("", outWriter.ToString());

            var result = ProcessUtilities.Run(Path.Combine(dir.Path, "sjis.exe"), arguments: "", workingDirectory: dir.Path);
            Assert.Equal(0, result.ExitCode);
            Assert.Equal("星野 八郎太", File.ReadAllText(Path.Combine(dir.Path, "output.txt"), Encoding.GetEncoding(932)));
        }
        public void CompilationWithWrongOutPath_04()
        {
            string source = @"
public class C
{
    public static void Main()
    {
    }
}";

            var fileName = "a.cs";
            var dir = Temp.CreateDirectory();
            var file = dir.CreateFile(fileName);
            file.WriteAllText(source);
            var outWriter = new StringWriter(CultureInfo.InvariantCulture);
            var csc = new MockCSharpCompiler(null, dir.Path, new[] { fileName, "/preferreduilang:en", "/target:exe", "/out: " });
            int exitCode = csc.Run(outWriter);

            Assert.Equal(1, exitCode);
            Assert.Contains("error CS2005: Missing file specification for '/out:' option", outWriter.ToString(), StringComparison.Ordinal);

            CleanupAllGeneratedFiles(file.Path);
        }