diff --git a/src/Compilers/CSharp/Test/CommandLine/CSharpCommandLineTest.csproj b/src/Compilers/CSharp/Test/CommandLine/CSharpCommandLineTest.csproj index 75b2cb63238df921f5eb9b676f0ce85af3a90568..50c9f8159d5c87b338fc302f7e8c39c247a0b5a3 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CSharpCommandLineTest.csproj +++ b/src/Compilers/CSharp/Test/CommandLine/CSharpCommandLineTest.csproj @@ -17,6 +17,10 @@ v4.5 + + {9929e5ae-85ca-46a8-a500-3be7bc634d87} + ServerCore + {4B45CA0C-03A0-400F-B454-3D4BCB16AF38} csc @@ -105,4 +109,4 @@ - + \ No newline at end of file diff --git a/src/Compilers/CSharp/Test/CommandLine/TouchedFileLoggingTests.cs b/src/Compilers/CSharp/Test/CommandLine/TouchedFileLoggingTests.cs index fc753d311a5e19d91e5a9b44002b550c3819296f..533ee1eb0af97111eb8e9ab4fa8ab214c9880ce6 100644 --- a/src/Compilers/CSharp/Test/CommandLine/TouchedFileLoggingTests.cs +++ b/src/Compilers/CSharp/Test/CommandLine/TouchedFileLoggingTests.cs @@ -215,6 +215,7 @@ public void TrivialMetadataCaching() filelist.Add(source1); var outWriter = new StringWriter(); var cmd = new CSharpCompilerServer( + new DesktopCompilerServerHost(), new[] { "/nologo", "/touchedfiles:" + touchedBase, source1 }, null, _baseDirectory, diff --git a/src/Compilers/Server/Core/ICompilerServerHost.cs b/src/Compilers/Server/Core/ICompilerServerHost.cs new file mode 100644 index 0000000000000000000000000000000000000000..9ffe0e6d4434f2b082ebdb99d8c9cf3c2bbca01b --- /dev/null +++ b/src/Compilers/Server/Core/ICompilerServerHost.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.CodeAnalysis.CompilerServer +{ + public interface ICompilerServerHost + { + Func AssemblyReferenceProvider { get; } + } +} diff --git a/src/Compilers/Server/VBCSCompiler/MetadataCache.cs b/src/Compilers/Server/Core/MetadataCache.cs similarity index 88% rename from src/Compilers/Server/VBCSCompiler/MetadataCache.cs rename to src/Compilers/Server/Core/MetadataCache.cs index e725bb8939d3bf2761b71556114b3bed86cfc90e..330fe664a6d4d5b8d1352b97f97c7baa389994e5 100644 --- a/src/Compilers/Server/VBCSCompiler/MetadataCache.cs +++ b/src/Compilers/Server/Core/MetadataCache.cs @@ -58,7 +58,6 @@ internal Metadata GetMetadata(string fullPath, MetadataReferenceProperties prope Metadata metadata; if (fileKey.HasValue && _metadataCache.TryGetValue(fileKey.Value, out metadata) && metadata != null) { - CompilerServerLogger.Log("Using already loaded metadata for assembly reference '{0}'", fileKey); return metadata; } @@ -92,20 +91,9 @@ internal Metadata GetMetadata(string fullPath, MetadataReferenceProperties prope /// private FileKey? GetUniqueFileKey(string filePath) { - FileInfo fileInfo; - try { - fileInfo = new FileInfo(filePath); - - if (!fileInfo.Exists) - { - return null; - } - else - { - return new FileKey(fileInfo.FullName, fileInfo.LastWriteTimeUtc); - } + return FileKey.Create(filePath); } catch (Exception) { @@ -117,11 +105,11 @@ internal Metadata GetMetadata(string fullPath, MetadataReferenceProperties prope } } - internal class CachingMetadataReference : PortableExecutableReference + public sealed class CachingMetadataReference : PortableExecutableReference { private static readonly MetadataAndSymbolCache s_mdCache = new MetadataAndSymbolCache(); - internal CachingMetadataReference(string fullPath, MetadataReferenceProperties properties) + public CachingMetadataReference(string fullPath, MetadataReferenceProperties properties) : base(properties, fullPath) { } diff --git a/src/Compilers/Server/Core/ServerCore.csproj b/src/Compilers/Server/Core/ServerCore.csproj index f88a65bfd71ac8361dc3b7897e2f45372818e8be..f7e653c5a6eb078629754f7883f4c73747684439 100644 --- a/src/Compilers/Server/Core/ServerCore.csproj +++ b/src/Compilers/Server/Core/ServerCore.csproj @@ -50,6 +50,10 @@ BasicCodeAnalysis + + + + diff --git a/src/Compilers/Server/VBCSCompiler/CSharpCompilerServer.cs b/src/Compilers/Server/VBCSCompiler/CSharpCompilerServer.cs index 6e24614f193712e0fa987b137d33a45f95c2c690..828068dbbf9f794aa5e446b03f5c7eb6aa789730 100644 --- a/src/Compilers/Server/VBCSCompiler/CSharpCompilerServer.cs +++ b/src/Compilers/Server/VBCSCompiler/CSharpCompilerServer.cs @@ -13,47 +13,17 @@ namespace Microsoft.CodeAnalysis.CompilerServer { internal sealed class CSharpCompilerServer : CSharpCompiler { - internal CSharpCompilerServer(string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string libDirectory, IAnalyzerAssemblyLoader analyzerLoader) - : base(CSharpCommandLineParser.Default, clientDirectory != null ? Path.Combine(clientDirectory, ResponseFileName) : null, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader) - { - } - - public static BuildResponse RunCompiler( - string clientDirectory, - string[] args, - string baseDirectory, - string sdkDirectory, - string libDirectory, - IAnalyzerAssemblyLoader analyzerLoader, - CancellationToken cancellationToken) - { - var compiler = new CSharpCompilerServer(args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader); - bool utf8output = compiler.Arguments.Utf8Output; - - if (!AnalyzerConsistencyChecker.Check(baseDirectory, compiler.Arguments.AnalyzerReferences, analyzerLoader)) - { - return new AnalyzerInconsistencyBuildResponse(); - } + private readonly ICompilerServerHost _compilerServerHost; - TextWriter output = new StringWriter(CultureInfo.InvariantCulture); - int returnCode = compiler.Run(output, cancellationToken); - - return new CompletedBuildResponse(returnCode, utf8output, output.ToString(), string.Empty); - } - - public override int Run(TextWriter consoleOutput, CancellationToken cancellationToken = default(CancellationToken)) + internal CSharpCompilerServer(ICompilerServerHost compilerServerHost, string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string libDirectory, IAnalyzerAssemblyLoader analyzerLoader) + : base(CSharpCommandLineParser.Default, clientDirectory != null ? Path.Combine(clientDirectory, ResponseFileName) : null, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader) { - int returnCode; - - CompilerServerLogger.Log("****Running C# compiler..."); - returnCode = base.Run(consoleOutput, cancellationToken); - CompilerServerLogger.Log("****C# Compilation complete.\r\n****Return code: {0}\r\n****Output:\r\n{1}\r\n", returnCode, consoleOutput.ToString()); - return returnCode; + _compilerServerHost = compilerServerHost; } internal override Func GetMetadataProvider() { - return CompilerRequestHandler.AssemblyReferenceProvider; + return _compilerServerHost.AssemblyReferenceProvider; } protected override uint GetSqmAppID() diff --git a/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs b/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs index 6ec5c8aa98004e7a5b444c8c416d5f83b2a9ce2b..d1817a0ea1767ebbc9c0924d60e04a60f2c95f96 100644 --- a/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs +++ b/src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs @@ -16,12 +16,10 @@ namespace Microsoft.CodeAnalysis.CompilerServer /// internal class CompilerRequestHandler : IRequestHandler { - // Caches are used by C# and VB compilers, and shared here. - public static readonly Func AssemblyReferenceProvider = - (path, properties) => new CachingMetadataReference(path, properties); - public static readonly IAnalyzerAssemblyLoader AnalyzerLoader = new ShadowCopyAnalyzerAssemblyLoader(Path.Combine(Path.GetTempPath(), "VBCSCompiler", "AnalyzerAssemblyLoader")); + private readonly DesktopCompilerServerHost _desktopCompilerServerHost = new DesktopCompilerServerHost(); + private static void LogAbnormalExit(string msg) { string roslynTempDir = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "RoslynCompilerServerCrash"); @@ -150,7 +148,8 @@ private BuildResponse CSharpCompile(BuildRequest req, CancellationToken cancella CompilerServerLogger.Log("Argument[{0}] = '{1}'", i, commandLineArguments[i]); } - return CSharpCompilerServer.RunCompiler( + + return CSharpCompileCore( responseFileDirectory, commandLineArguments, currentDirectory, @@ -160,6 +159,31 @@ private BuildResponse CSharpCompile(BuildRequest req, CancellationToken cancella cancellationToken); } + private BuildResponse CSharpCompileCore( + string clientDirectory, + string[] args, + string baseDirectory, + string sdkDirectory, + string libDirectory, + IAnalyzerAssemblyLoader analyzerLoader, + CancellationToken cancellationToken) + { + var compiler = new CSharpCompilerServer(_desktopCompilerServerHost, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader); + bool utf8output = compiler.Arguments.Utf8Output; + + if (!AnalyzerConsistencyChecker.Check(baseDirectory, compiler.Arguments.AnalyzerReferences, analyzerLoader)) + { + return new AnalyzerInconsistencyBuildResponse(); + } + + CompilerServerLogger.Log("****Running C# compiler..."); + TextWriter output = new StringWriter(CultureInfo.InvariantCulture); + int returnCode = compiler.Run(output, cancellationToken); + CompilerServerLogger.Log("****C# Compilation complete.\r\n****Return code: {0}\r\n****Output:\r\n{1}\r\n", returnCode, output.ToString()); + + return new CompletedBuildResponse(returnCode, utf8output, output.ToString(), string.Empty); + } + /// /// A request to compile VB files. Unpack the arguments and current directory and invoke /// the compiler, then create a response with the result of compilation. @@ -204,7 +228,7 @@ private BuildResponse BasicCompile(BuildRequest req, CancellationToken cancellat CompilerServerLogger.Log("Argument[{0}] = '{1}'", i, commandLineArguments[i]); } - return VisualBasicCompilerServer.RunCompiler( + return BasicCompileCore( responseFileDirectory, commandLineArguments, currentDirectory, @@ -213,5 +237,31 @@ private BuildResponse BasicCompile(BuildRequest req, CancellationToken cancellat AnalyzerLoader, cancellationToken); } + + private BuildResponse BasicCompileCore( + string clientDirectory, + string[] args, + string baseDirectory, + string sdkDirectory, + string libDirectory, + IAnalyzerAssemblyLoader analyzerLoader, + CancellationToken cancellationToken) + { + var compiler = new VisualBasicCompilerServer(_desktopCompilerServerHost, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader); + bool utf8output = compiler.Arguments.Utf8Output; + + if (!AnalyzerConsistencyChecker.Check(baseDirectory, compiler.Arguments.AnalyzerReferences, analyzerLoader)) + { + return new AnalyzerInconsistencyBuildResponse(); + } + + TextWriter output = new StringWriter(CultureInfo.InvariantCulture); + CompilerServerLogger.Log("****Running VB compiler..."); + int returnCode = compiler.Run(output, cancellationToken); + CompilerServerLogger.Log("****VB Compilation complete.\r\n****Return code: {0}\r\n****Output:\r\n{1}\r\n", returnCode, output.ToString()); + + return new CompletedBuildResponse(returnCode, utf8output, output.ToString(), string.Empty); + } + } } diff --git a/src/Compilers/Server/VBCSCompiler/DesktopCompilerServerHost.cs b/src/Compilers/Server/VBCSCompiler/DesktopCompilerServerHost.cs new file mode 100644 index 0000000000000000000000000000000000000000..e004d69a7188aefd4f96173c649925ce5447d789 --- /dev/null +++ b/src/Compilers/Server/VBCSCompiler/DesktopCompilerServerHost.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.CodeAnalysis.CompilerServer +{ + internal sealed class DesktopCompilerServerHost : ICompilerServerHost + { + // Caches are used by C# and VB compilers, and shared here. + private static readonly Func s_assemblyReferenceProvider = + (path, properties) => new CachingMetadataReference(path, properties); + + public Func AssemblyReferenceProvider => s_assemblyReferenceProvider; + } +} diff --git a/src/Compilers/Server/VBCSCompiler/VBCSCompiler.csproj b/src/Compilers/Server/VBCSCompiler/VBCSCompiler.csproj index 73222d40894e8ae3ed33fbc7ab54970c47e7787c..70b32e9d589c41e0f835a3890906c4bb738f5a8d 100644 --- a/src/Compilers/Server/VBCSCompiler/VBCSCompiler.csproj +++ b/src/Compilers/Server/VBCSCompiler/VBCSCompiler.csproj @@ -65,9 +65,9 @@ + - diff --git a/src/Compilers/Server/VBCSCompiler/VisualBasicCompilerServer.cs b/src/Compilers/Server/VBCSCompiler/VisualBasicCompilerServer.cs index 2026d2bbf830f7926ff4b0ab8dd76f0fc48d79e2..7e51fd18101399b38a2da0a89ffd5bd4e8858635 100644 --- a/src/Compilers/Server/VBCSCompiler/VisualBasicCompilerServer.cs +++ b/src/Compilers/Server/VBCSCompiler/VisualBasicCompilerServer.cs @@ -15,46 +15,17 @@ namespace Microsoft.CodeAnalysis.CompilerServer { internal sealed class VisualBasicCompilerServer : VisualBasicCompiler { - internal VisualBasicCompilerServer(string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string libDirectory, IAnalyzerAssemblyLoader analyzerLoader) - : base(VisualBasicCommandLineParser.Default, clientDirectory != null ? Path.Combine(clientDirectory, ResponseFileName) : null, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader) - { - } - - public static BuildResponse RunCompiler( - string clientDirectory, - string[] args, - string baseDirectory, - string sdkDirectory, - string libDirectory, - IAnalyzerAssemblyLoader analyzerLoader, - CancellationToken cancellationToken) - { - var compiler = new VisualBasicCompilerServer(args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader); - bool utf8output = compiler.Arguments.Utf8Output; + private readonly ICompilerServerHost _compilerServerHost; - if (!AnalyzerConsistencyChecker.Check(baseDirectory, compiler.Arguments.AnalyzerReferences, analyzerLoader)) - { - return new AnalyzerInconsistencyBuildResponse(); - } - - TextWriter output = new StringWriter(CultureInfo.InvariantCulture); - int returnCode = compiler.Run(output, cancellationToken); - - return new CompletedBuildResponse(returnCode, utf8output, output.ToString(), string.Empty); - } - - public override int Run(TextWriter consoleOutput, CancellationToken cancellationToken) + internal VisualBasicCompilerServer(ICompilerServerHost compilerServerHost, string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string libDirectory, IAnalyzerAssemblyLoader analyzerLoader) + : base(VisualBasicCommandLineParser.Default, clientDirectory != null ? Path.Combine(clientDirectory, ResponseFileName) : null, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory, analyzerLoader) { - int runResult; - CompilerServerLogger.Log("****Running VB compiler..."); - runResult = base.Run(consoleOutput, cancellationToken); - CompilerServerLogger.Log("****VB Compilation complete.\r\n****Return code: {0}\r\n****Output:\r\n{1}\r\n", runResult, consoleOutput.ToString()); - return runResult; + _compilerServerHost = compilerServerHost; } internal override Func GetMetadataProvider() { - return CompilerRequestHandler.AssemblyReferenceProvider; + return _compilerServerHost.AssemblyReferenceProvider; } protected override uint GetSqmAppID() diff --git a/src/Compilers/VisualBasic/Test/CommandLine/BasicCommandLineTest.vbproj b/src/Compilers/VisualBasic/Test/CommandLine/BasicCommandLineTest.vbproj index a6490865f60ed688e7afc1815827fd3fd740834e..18a09d7ebf9f05f30c2b13b4f9700d3037d9ed1d 100644 --- a/src/Compilers/VisualBasic/Test/CommandLine/BasicCommandLineTest.vbproj +++ b/src/Compilers/VisualBasic/Test/CommandLine/BasicCommandLineTest.vbproj @@ -22,6 +22,10 @@ {76C6F005-C89D-4348-BB4A-391898DBEB52} TestUtilities.Desktop + + {9929e5ae-85ca-46a8-a500-3be7bc634d87} + ServerCore + {9508F118-F62E-4C16-A6F4-7C3B56E166AD} VBCSCompiler @@ -136,4 +140,4 @@ - + \ No newline at end of file diff --git a/src/Compilers/VisualBasic/Test/CommandLine/TouchedFileLoggingTests.vb b/src/Compilers/VisualBasic/Test/CommandLine/TouchedFileLoggingTests.vb index c28de9fda579954fc8562bf40f536dcfdb797c23..4019c0802acba9415400f908a14fd8fd9c7d29e2 100644 --- a/src/Compilers/VisualBasic/Test/CommandLine/TouchedFileLoggingTests.vb +++ b/src/Compilers/VisualBasic/Test/CommandLine/TouchedFileLoggingTests.vb @@ -169,6 +169,7 @@ End Class Dim outWriter = New StringWriter() Dim cmd = New VisualBasicCompilerServer( + New DesktopCompilerServerHost(), {"/nologo", "/touchedfiles:" + touchedBase, source1},