提交 66d18e41 编写于 作者: J Jared Parsons

More CoreFx changes

This has a number of small changes necessary for CoreFx support:

- Thread through the client directory to CommonCompiler.  This is
necessary for loading items like the SqmData.
- Move GetAssemblyVersion and GetAssemblyFileVersion into
CommonCompiler.  There is no need to specialize this for each compiler.
- Change the implementation of the above methods to not rely on
Assembly.Location which isn't present in CoreFx.

closes #1974
上级 1541b81c
......@@ -19,14 +19,11 @@ internal abstract class CSharpCompiler : CommonCompiler
{
internal const string ResponseFileName = "csc.rsp";
private readonly string _responseFile;
private CommandLineDiagnosticFormatter _diagnosticFormatter;
protected CSharpCompiler(CSharpCommandLineParser parser, string responseFile, string[] args, string baseDirectory, string sdkDirectory, string additionalReferenceDirectories)
: base(parser, responseFile, args, baseDirectory, sdkDirectory, additionalReferenceDirectories)
protected CSharpCompiler(CSharpCommandLineParser parser, string responseFile, string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string additionalReferenceDirectories)
: base(parser, responseFile, args, clientDirectory, baseDirectory, sdkDirectory, additionalReferenceDirectories)
{
Debug.Assert(responseFile == null || Path.IsPathRooted(responseFile));
_responseFile = responseFile;
_diagnosticFormatter = new CommandLineDiagnosticFormatter(baseDirectory, Arguments.PrintFullPaths, Arguments.ShouldIncludeErrorEndLocation);
}
......@@ -260,16 +257,6 @@ internal override string GetToolName()
return ErrorFacts.GetMessage(MessageID.IDS_ToolName, Culture);
}
internal override string GetAssemblyFileVersion()
{
return FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
}
internal override Version GetAssemblyVersion()
{
return Assembly.GetExecutingAssembly().GetName().Version;
}
/// <summary>
/// Print Commandline help message (up to 80 English characters per line)
/// </summary>
......
......@@ -976,7 +976,7 @@ public new CSharpCommandLineArguments Parse(IEnumerable<string> args, string bas
if (!noStdLib)
{
metadataReferences.Insert(0, new CommandLineReference(typeof(object).Assembly.Location, MetadataReferenceProperties.Assembly));
metadataReferences.Insert(0, new CommandLineReference(Path.Combine(sdkDirectory, "mscorlib.dll"), MetadataReferenceProperties.Assembly));
}
if (!platform.Requires64Bit())
......
......@@ -213,8 +213,9 @@ public void TrivialMetadataCaching()
filelist.Add(source1);
var outWriter = new StringWriter();
var cmd = new CSharpCompilerServer(null,
var cmd = new CSharpCompilerServer(
new[] { "/nologo", "/touchedfiles:" + touchedBase, source1 },
null,
_baseDirectory,
RuntimeEnvironment.GetRuntimeDirectory(),
s_libDirectory);
......
......@@ -12,17 +12,17 @@ namespace Microsoft.CodeAnalysis.CSharp.CommandLine
{
internal sealed class Csc : CSharpCompiler
{
internal Csc(string responseFile, string baseDirectory, string sdkDirectory, string[] args)
: base(CSharpCommandLineParser.Default, responseFile, args, baseDirectory, sdkDirectory, Environment.GetEnvironmentVariable("LIB"))
internal Csc(string responseFile, string clientDirectory, string baseDirectory, string sdkDirectory, string[] args)
: base(CSharpCommandLineParser.Default, responseFile, args, clientDirectory, baseDirectory, sdkDirectory, Environment.GetEnvironmentVariable("LIB"))
{
}
internal static int Run(string clientDir, string sdkDirectory, string[] args)
internal static int Run(string clientDirectory, string sdkDirectory, string[] args)
{
FatalError.Handler = FailFast.OnFatalException;
var responseFile = Path.Combine(clientDir, CSharpCompiler.ResponseFileName);
Csc compiler = new Csc(responseFile, Directory.GetCurrentDirectory(), sdkDirectory, args);
var responseFile = Path.Combine(clientDirectory, CSharpCompiler.ResponseFileName);
Csc compiler = new Csc(responseFile, clientDirectory, Directory.GetCurrentDirectory(), sdkDirectory, args);
return ConsoleUtil.RunWithOutput(compiler.Arguments.Utf8Output, (textWriterOut, _) => compiler.Run(textWriterOut));
}
......
......@@ -26,6 +26,8 @@ internal abstract partial class CommonCompiler
internal const int Failed = 1;
internal const int Succeeded = 0;
private readonly string _clientDirectory;
public CommonMessageProvider MessageProvider { get; private set; }
public CommandLineArguments Arguments { get; private set; }
public abstract DiagnosticFormatter DiagnosticFormatter { get; }
......@@ -35,20 +37,18 @@ internal abstract partial class CommonCompiler
public abstract void PrintLogo(TextWriter consoleOutput);
public abstract void PrintHelp(TextWriter consoleOutput);
internal abstract string GetToolName();
internal abstract Version GetAssemblyVersion();
internal abstract string GetAssemblyFileVersion();
protected abstract uint GetSqmAppID();
protected abstract bool TryGetCompilerDiagnosticCode(string diagnosticId, out uint code);
protected abstract void CompilerSpecificSqm(IVsSqmMulti sqm, uint sqmSession);
protected abstract ImmutableArray<DiagnosticAnalyzer> ResolveAnalyzersFromArguments(List<DiagnosticInfo> diagnostics, CommonMessageProvider messageProvider, TouchedFileLogger touchedFiles);
public CommonCompiler(CommandLineParser parser, string responseFile, string[] args, string baseDirectory, string sdkDirectory, string additionalReferenceDirectories)
public CommonCompiler(CommandLineParser parser, string responseFile, string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string additionalReferenceDirectories)
{
IEnumerable<string> allArgs = args;
_clientDirectory = clientDirectory;
Debug.Assert(null == responseFile || PathUtilities.IsAbsolute(responseFile));
if (!SuppressDefaultResponseFile(args) && File.Exists(responseFile))
{
allArgs = new[] { "@" + responseFile }.Concat(allArgs);
......@@ -62,6 +62,23 @@ public CommonCompiler(CommandLineParser parser, string responseFile, string[] ar
public abstract Assembly LoadAssembly(string fullPath);
internal string GetAssemblyFileVersion()
{
if (_clientDirectory != null)
{
var name = $"{typeof(CommonCompiler).GetTypeInfo().Assembly.GetName().Name}.dll";
var filePath = Path.Combine(_clientDirectory, name);
return FileVersionInfo.GetVersionInfo(filePath).FileVersion;
}
return "";
}
internal Version GetAssemblyVersion()
{
return typeof(CommonCompiler).GetTypeInfo().Assembly.GetName().Version;
}
internal virtual MetadataFileReferenceProvider GetMetadataProvider()
{
return MetadataFileReferenceProvider.Default;
......@@ -537,16 +554,14 @@ private void GenerateSqmData(CompilationOptions compilationOptions, ImmutableArr
uint sqmSession = 0u;
try
{
sqm = SqmServiceProvider.TryGetSqmService();
sqm = SqmServiceProvider.TryGetSqmService(_clientDirectory);
if (sqm != null)
{
sqm.BeginSession(this.GetSqmAppID(), false, out sqmSession);
sqm.SetGlobalSessionGuid(Arguments.SqmSessionGuid);
// Build Version
Assembly thisAssembly = typeof(CommonCompiler).Assembly;
var fileVersion = FileVersionInfo.GetVersionInfo(thisAssembly.Location).FileVersion;
sqm.SetStringDatapoint(sqmSession, SqmServiceProvider.DATAID_SQM_BUILDVERSION, fileVersion);
sqm.SetStringDatapoint(sqmSession, SqmServiceProvider.DATAID_SQM_BUILDVERSION, GetAssemblyFileVersion());
// Write Errors and Warnings from build
foreach (var diagnostic in diagnostics)
......
......@@ -8,7 +8,7 @@
namespace Microsoft.CodeAnalysis.Interop
{
[ComImport, ComConversionLoss, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D"), SuppressUnmanagedCodeSecurity]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D"), SuppressUnmanagedCodeSecurity]
internal interface IClrStrongName
{
void GetHashFromAssemblyFile(
......
......@@ -5,6 +5,7 @@
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
namespace Microsoft.VisualStudio.Shell.Interop
{
......@@ -44,21 +45,22 @@ public enum CompilerType
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(String libPath);
private static Lazy<QueryServiceDelegate> s_queryService = new Lazy<QueryServiceDelegate>(TryGetSqmServiceDelegate, true);
private static Optional<QueryServiceDelegate> s_queryService;
private static readonly object s_guard = new object();
private static QueryServiceDelegate TryGetSqmServiceDelegate()
private static QueryServiceDelegate TryGetSqmServiceDelegateCore(string baseDirectory)
{
try
{
IntPtr vssqmdll = IntPtr.Zero;
string vssqmpath = AppDomain.CurrentDomain.BaseDirectory;
if (Environment.Is64BitProcess)
string vssqmpath;
if (IntPtr.Size == 8)
{
vssqmpath = Path.Combine(vssqmpath, @"sqmamd64\vssqmmulti.dll");
vssqmpath = Path.Combine(baseDirectory, @"sqmamd64\vssqmmulti.dll");
}
else
{
vssqmpath = Path.Combine(vssqmpath, @"sqmx86\vssqmmulti.dll");
vssqmpath = Path.Combine(baseDirectory, @"sqmx86\vssqmmulti.dll");
}
vssqmdll = SqmServiceProvider.LoadLibrary(vssqmpath);
if (vssqmdll != IntPtr.Zero)
......@@ -74,16 +76,30 @@ private static QueryServiceDelegate TryGetSqmServiceDelegate()
return null;
}
public static IVsSqmMulti TryGetSqmService()
private static QueryServiceDelegate TryGetSqmServiceDelegate(string baseDirectory)
{
lock (s_guard)
{
if (!s_queryService.HasValue)
{
s_queryService = TryGetSqmServiceDelegateCore(baseDirectory);
}
return s_queryService.Value;
}
}
public static IVsSqmMulti TryGetSqmService(string baseDirectory)
{
IVsSqmMulti result = null;
Guid rsid = new Guid("2508FDF0-EF80-4366-878E-C9F024B8D981");
Guid riid = new Guid("B17A7D4A-C1A3-45A2-B916-826C3ABA067E");
if (s_queryService.Value != null)
QueryServiceDelegate queryService = TryGetSqmServiceDelegate(baseDirectory);
if (queryService != null)
{
try
{
s_queryService.Value(ref rsid, ref riid, out result);
queryService(ref rsid, ref riid, out result);
}
catch (Exception e)
{
......
......@@ -13,13 +13,13 @@ namespace Microsoft.CodeAnalysis.CompilerServer
{
internal sealed class CSharpCompilerServer : CSharpCompiler
{
internal CSharpCompilerServer(string responseFile, string[] args, string baseDirectory, string sdkDirectory, string libDirectory)
: base(CSharpCommandLineParser.Default, responseFile, args, baseDirectory, sdkDirectory, libDirectory)
internal CSharpCompilerServer(string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string libDirectory)
: base(CSharpCommandLineParser.Default, clientDirectory != null ? Path.Combine(clientDirectory, ResponseFileName) : null, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory)
{
}
public static int RunCompiler(
string responseFileDirectory,
string clientDirectory,
string[] args,
string baseDirectory,
string sdkDirectory,
......@@ -28,8 +28,7 @@ internal CSharpCompilerServer(string responseFile, string[] args, string baseDir
CancellationToken cancellationToken,
out bool utf8output)
{
var responseFile = Path.Combine(responseFileDirectory, CSharpCompiler.ResponseFileName);
var compiler = new CSharpCompilerServer(responseFile, args, baseDirectory, sdkDirectory, libDirectory);
var compiler = new CSharpCompilerServer(args, clientDirectory, baseDirectory, sdkDirectory, libDirectory);
utf8output = compiler.Arguments.Utf8Output;
return compiler.Run(output, cancellationToken);
}
......
......@@ -15,13 +15,13 @@ namespace Microsoft.CodeAnalysis.CompilerServer
{
internal sealed class VisualBasicCompilerServer : VisualBasicCompiler
{
internal VisualBasicCompilerServer(string responseFile, string[] args, string baseDirectory, string sdkDirectory, string libDirectory)
: base(VisualBasicCommandLineParser.Default, responseFile, args, baseDirectory, sdkDirectory, libDirectory)
internal VisualBasicCompilerServer(string[] args, string clientDirectory, string baseDirectory, string sdkDirectory, string libDirectory)
: base(VisualBasicCommandLineParser.Default, clientDirectory != null ? Path.Combine(clientDirectory, ResponseFileName) : null, args, clientDirectory, baseDirectory, sdkDirectory, libDirectory)
{
}
public static int RunCompiler(
string responseFileDirectory,
string clientDirectory,
string[] args,
string baseDirectory,
string sdkDirectory,
......@@ -30,8 +30,7 @@ internal VisualBasicCompilerServer(string responseFile, string[] args, string ba
CancellationToken cancellationToken,
out bool utf8output)
{
var responseFile = Path.Combine(responseFileDirectory, VisualBasicCompiler.ResponseFileName);
var compiler = new VisualBasicCompilerServer(responseFile, args, baseDirectory, sdkDirectory, libDirectory);
var compiler = new VisualBasicCompilerServer(args, clientDirectory, baseDirectory, sdkDirectory, libDirectory);
utf8output = compiler.Arguments.Utf8Output;
return compiler.Run(output, cancellationToken);
}
......
......@@ -23,7 +23,7 @@ public MockCSharpCompiler(string responseFile, string baseDirectory, string[] ar
}
public MockCSharpCompiler(string responseFile, string baseDirectory, string[] args, ImmutableArray<DiagnosticAnalyzer> analyzers)
: base(CSharpCommandLineParser.Default, responseFile, args, baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Environment.GetEnvironmentVariable("LIB"))
: base(CSharpCommandLineParser.Default, responseFile, args, Path.GetDirectoryName(typeof(CSharpCompiler).Assembly.Location), baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Environment.GetEnvironmentVariable("LIB"))
{
_analyzers = analyzers;
}
......
// 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.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
......@@ -13,8 +12,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities
{
internal class MockCsi : CSharpCompiler
{
public MockCsi(string responseFIle, string baseDirectory, string[] args)
: base(CSharpCommandLineParser.Interactive, responseFIle, args, baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), null)
public MockCsi(string responseFile, string baseDirectory, string[] args)
: base(CSharpCommandLineParser.Interactive, responseFile, args, Path.GetDirectoryName(typeof(CSharpCompiler).Assembly.Location), baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), null)
{
}
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.IO
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.VisualBasic
......@@ -9,7 +10,7 @@ Friend Class MockVbi
Inherits VisualBasicCompiler
Public Sub New(responseFile As String, baseDirectory As String, args As String())
MyBase.New(VisualBasicCommandLineParser.Interactive, responseFile, args, baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Nothing)
MyBase.New(VisualBasicCommandLineParser.Interactive, responseFile, args, Path.GetDirectoryName(GetType(VisualBasicCompiler).Assembly.Location), baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Nothing)
End Sub
......
......@@ -22,7 +22,7 @@ Friend Class MockVisualBasicCompiler
End Sub
Public Sub New(responseFile As String, baseDirectory As String, args As String(), analyzers As ImmutableArray(Of DiagnosticAnalyzer))
MyBase.New(VisualBasicCommandLineParser.Default, responseFile, args, baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Environment.GetEnvironmentVariable("LIB"))
MyBase.New(VisualBasicCommandLineParser.Default, responseFile, args, Path.GetDirectoryName(GetType(VisualBasicCompiler).Assembly.Location), baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Environment.GetEnvironmentVariable("LIB"))
_analyzers = analyzers
End Sub
......
......@@ -18,10 +18,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private ReadOnly _responseFile As String
Private ReadOnly _diagnosticFormatter As CommandLineDiagnosticFormatter
Protected Sub New(parser As VisualBasicCommandLineParser, responseFile As String, args As String(), baseDirectory As String, sdkDirectory As String, additionalReferenceDirectories As String)
MyBase.New(parser, responseFile, args, baseDirectory, sdkDirectory, additionalReferenceDirectories)
Debug.Assert(responseFile Is Nothing OrElse Path.IsPathRooted(responseFile))
_responseFile = responseFile
Protected Sub New(parser As VisualBasicCommandLineParser, responseFile As String, args As String(), clientDirectory As String, baseDirectory As String, sdkDirectory As String, additionalReferenceDirectories As String)
MyBase.New(parser, responseFile, args, clientDirectory, baseDirectory, sdkDirectory, additionalReferenceDirectories)
_diagnosticFormatter = New CommandLineDiagnosticFormatter(baseDirectory)
End Sub
......@@ -179,14 +177,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return ErrorFactory.IdToString(ERRID.IDS_ToolName, Culture)
End Function
Friend Overrides Function GetAssemblyFileVersion() As String
Return FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion
End Function
Friend Overrides Function GetAssemblyVersion() As Version
Return Assembly.GetExecutingAssembly().GetName().Version
End Function
''' <summary>
''' Print Commandline help message (up to 80 English characters per line)
''' </summary>
......
......@@ -167,10 +167,11 @@ End Class
folderList.Add(touchedDir.Path)
Dim outWriter = New StringWriter()
Dim cmd = New VisualBasicCompilerServer(Nothing,
Dim cmd = New VisualBasicCompilerServer(
{"/nologo",
"/touchedfiles:" + touchedBase,
source1},
Nothing,
_baseDirectory,
RuntimeEnvironment.GetRuntimeDirectory(),
s_libDirectory)
......
......@@ -11,17 +11,17 @@ namespace Microsoft.CodeAnalysis.VisualBasic.CommandLine
{
internal sealed class Vbc : VisualBasicCompiler
{
internal Vbc(string responseFile, string baseDirectory, string sdkDirectory, string[] args)
: base(VisualBasicCommandLineParser.Default, responseFile, args, baseDirectory, sdkDirectory, Environment.GetEnvironmentVariable("LIB"))
internal Vbc(string responseFile, string clientDirectory, string baseDirectory, string sdkDirectory, string[] args)
: base(VisualBasicCommandLineParser.Default, responseFile, args, clientDirectory, baseDirectory, sdkDirectory, Environment.GetEnvironmentVariable("LIB"))
{
}
internal static int Run(string clientDir, string sdkDirectory, string[] args)
internal static int Run(string clientDirectory, string sdkDirectory, string[] args)
{
FatalError.Handler = FailFast.OnFatalException;
var responseFile = Path.Combine(clientDir, VisualBasicCompiler.ResponseFileName);
Vbc compiler = new Vbc(responseFile, Directory.GetCurrentDirectory(), sdkDirectory, args);
var responseFile = Path.Combine(clientDirectory, VisualBasicCompiler.ResponseFileName);
Vbc compiler = new Vbc(responseFile, clientDirectory, Directory.GetCurrentDirectory(), sdkDirectory, args);
return ConsoleUtil.RunWithOutput(compiler.Arguments.Utf8Output, (textWriterOut, _) => compiler.Run(textWriterOut));
}
......
......@@ -20,7 +20,7 @@ internal sealed class Csi : CSharpCompiler
private const string InteractiveResponseFileName = "csi.rsp";
internal Csi(string responseFile, string baseDirectory, string[] args)
: base(CSharpCommandLineParser.Interactive, responseFile, args, baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), null /* TODO: what to pass as additionalReferencePaths? */)
: base(CSharpCommandLineParser.Interactive, responseFile, args, Path.GetDirectoryName(typeof(CSharpCompiler).Assembly.Location), baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), null /* TODO: what to pass as additionalReferencePaths? */)
{
}
......
......@@ -18,7 +18,7 @@ Friend NotInheritable Class Vbi
Friend Const InteractiveResponseFileName As String = "vbi.rsp"
Friend Sub New(responseFile As String, baseDirectory As String, args As String())
MyBase.New(VisualBasicCommandLineParser.Interactive, responseFile, args, baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Nothing) ' TODO: what to pass as additionalReferencePaths?
MyBase.New(VisualBasicCommandLineParser.Interactive, responseFile, args, Path.GetDirectoryName(GetType(VisualBasicCompiler).Assembly.Location), baseDirectory, RuntimeEnvironment.GetRuntimeDirectory(), Nothing) ' TODO: what to pass as additionalReferencePaths?
End Sub
Public Shared Function Main(args As String()) As Integer
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册