/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Server/VBCSCompilerTests/TouchedFileLoggingTests.cs
195 строк
7 KB
Jared Parsons
Rework analyzer assembly loading (#77004)
24 мар 2025, 20:11
Не верифицирован
24 мар 2025, 20:11
28b8657
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using static Roslyn.Test.Utilities.SharedResourceHelpers; using System.Reflection; using Microsoft.CodeAnalysis.CompilerServer; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.VisualBasic; namespace Microsoft.CodeAnalysis.CompilerServer.UnitTests { public class TouchedFileLoggingTests : TestBase { private static readonly string s_libDirectory = Environment.GetEnvironmentVariable("LIB"); private readonly string _baseDirectory = TempRoot.Root; private const string HelloWorldCS = @"using System; class C { public static void Main(string[] args) { Console.WriteLine(""Hello, world""); } }"; private const string HelloWorldVB = @"Imports System Class C Shared Sub Main(args As String()) Console.WriteLine(""Hello, world"") End Sub End Class "; [ConditionalFact(typeof(DesktopOnly))] public void CSharpTrivialMetadataCaching() { var loader = AnalyzerAssemblyLoader.CreateNonLockingLoader(Temp.CreateDirectory().Path); var filelist = new List<string>(); // Do the following compilation twice. // The compiler server API should hold on to the mscorlib bits // in memory, but the file tracker should still map that it was // touched. for (int i = 0; i < 2; i++) { var source1 = Temp.CreateFile().WriteAllText(HelloWorldCS).Path; var touchedDir = Temp.CreateDirectory(); var touchedBase = Path.Combine(touchedDir.Path, "touched"); var clientDirectory = AppContext.BaseDirectory; filelist.Add(source1); var outWriter = new StringWriter(); var cmd = new CSharpCompilerServer( CompilerServerHost.SharedAssemblyReferenceProvider, responseFile: null, new[] { "/nologo", "/touchedfiles:" + touchedBase, source1 }, new BuildPaths(clientDirectory, _baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Path.GetTempPath()), s_libDirectory, loader, driverCache: null); List<string> expectedReads; List<string> expectedWrites; BuildTouchedFiles(cmd, Path.ChangeExtension(source1, "exe"), out expectedReads, out expectedWrites); var exitCode = cmd.Run(outWriter); Assert.Equal(string.Empty, outWriter.ToString().Trim()); Assert.Equal(0, exitCode); AssertTouchedFilesEqual(expectedReads, expectedWrites, touchedBase); } foreach (String f in filelist) { CleanupAllGeneratedFiles(f); } } [ConditionalFact(typeof(DesktopOnly))] public void VisualBasicTrivialMetadataCaching() { var loader = AnalyzerAssemblyLoader.CreateNonLockingLoader(Temp.CreateDirectory().Path); var filelist = new List<string>(); // Do the following compilation twice. // The compiler server API should hold on to the mscorlib bits // in memory, but the file tracker should still map that it was // touched. for (int i = 0; i < 2; i++) { var source1 = Temp.CreateFile().WriteAllText(HelloWorldVB).Path; var touchedDir = Temp.CreateDirectory(); var touchedBase = Path.Combine(touchedDir.Path, "touched"); var clientDirectory = AppContext.BaseDirectory; filelist.Add(source1); var outWriter = new StringWriter(); var cmd = new VisualBasicCompilerServer( CompilerServerHost.SharedAssemblyReferenceProvider, responseFile: null, new[] { "/nologo", "/touchedfiles:" + touchedBase, source1 }, new BuildPaths(clientDirectory, _baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Path.GetTempPath()), s_libDirectory, loader, driverCache: null); List<string> expectedReads; List<string> expectedWrites; BuildTouchedFiles(cmd, Path.ChangeExtension(source1, "exe"), out expectedReads, out expectedWrites); var exitCode = cmd.Run(outWriter); Assert.Equal(string.Empty, outWriter.ToString().Trim()); Assert.Equal(0, exitCode); AssertTouchedFilesEqual(expectedReads, expectedWrites, touchedBase); } foreach (string f in filelist) { CleanupAllGeneratedFiles(f); } } /// <summary> /// Builds the expected base of touched files. /// Adds a hook for temporary file creation as well, /// so this method must be called before the execution of /// Csc.Run. /// </summary> private static void BuildTouchedFiles(CommonCompiler cmd, string outputPath, out List<string> expectedReads, out List<string> expectedWrites) { expectedReads = new List<string>(); expectedReads.AddRange(cmd.Arguments.MetadataReferences.Select(r => r.Reference)); if (cmd.Arguments is VisualBasicCommandLineArguments { DefaultCoreLibraryReference: { } reference }) { expectedReads.Add(reference.Reference); } foreach (var file in cmd.Arguments.SourceFiles) { expectedReads.Add(file.Path); } var writes = new List<string>(); writes.Add(outputPath); expectedWrites = writes; } private static void AssertTouchedFilesEqual( List<string> expectedReads, List<string> expectedWrites, string touchedFilesBase) { var touchedReadPath = touchedFilesBase + ".read"; var touchedWritesPath = touchedFilesBase + ".write"; var expected = expectedReads.Select(s => s.ToUpperInvariant()).OrderBy(s => s); Assert.Equal(string.Join("\r\n", expected), File.ReadAllText(touchedReadPath).Trim()); expected = expectedWrites.Select(s => s.ToUpperInvariant()).OrderBy(s => s); Assert.Equal(string.Join("\r\n", expected), File.ReadAllText(touchedWritesPath).Trim()); } } }