Remove private reflection in the compiler

This removes the remaining private reflection code from the compiler and
replaces it with multi-targeting approaches.
上级 ebd4e3da
......@@ -1373,7 +1373,7 @@ private void ConfirmModuleAttributePresentAndAddingToAssemblyResultsInSignedOutp
//confirm file does not claim to be signed
Assert.Equal(0, (int)(flags & CorFlags.StrongNameSigned));
var corlibName = CoreClrShim.IsRunningOnCoreClr ? "netstandard" : "mscorlib";
var corlibName = RuntimeUtilities.IsCoreClrRuntime ? "netstandard" : "mscorlib";
EntityHandle token = metadata.Module.GetTypeRef(metadata.Module.GetAssemblyRef(corlibName), "System.Runtime.CompilerServices", "AssemblyAttributesGoHere");
Assert.False(token.IsNil); //could the type ref be located? If not then the attribute's not there.
var attrInfos = metadata.Module.FindTargetAttributes(token, expectedModuleAttr);
......
......@@ -27,6 +27,7 @@
<PackageReference Include="Microsoft.DiaSymReader.Native" Version="$(MicrosoftDiaSymReaderNativeVersion)"/>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Shared\RuntimeHostInfo.cs" />
<Compile Include="..\..\Shared\NamedPipeUtil.cs" />
<Compile Include="..\..\Shared\BuildClient.cs">
<Link>BuildClient.cs</Link>
......
// 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.IO;
using Microsoft.Build.Utilities;
namespace Microsoft.CodeAnalysis.BuildTasks
......@@ -17,6 +18,8 @@ public abstract class ManagedToolTask : ToolTask
protected abstract string PathToManagedTool { get; }
protected string PathToManagedToolWithoutExtension => Path.ChangeExtension(PathToManagedTool, string.Empty);
/// <summary>
/// Note: "Native" here does not necessarily mean "native binary".
/// "Native" in this context means "native invocation", and running the executable directly.
......@@ -31,14 +34,9 @@ public abstract class ManagedToolTask : ToolTask
protected sealed override string GenerateCommandLineCommands()
{
var commandLineArguments = ToolArguments;
if (IsManagedTool && IsCliHost(out string pathToDotnet))
if (IsManagedTool)
{
var pathToTool = PathToManagedTool;
if (pathToTool is null)
{
Log.LogErrorWithCodeFromResources("General_ToolFileNotFound", ToolName);
}
commandLineArguments = PrependFileToArgs(pathToTool, commandLineArguments);
(_, commandLineArguments, _) = RuntimeHostInfo.GetProcessInfo(PathToManagedToolWithoutExtension, commandLineArguments);
}
return commandLineArguments;
......@@ -51,21 +49,9 @@ protected sealed override string GenerateCommandLineCommands()
/// </summary>
protected sealed override string GenerateFullPathToTool()
{
if (IsManagedTool)
{
if (IsCliHost(out string pathToDotnet))
{
return pathToDotnet;
}
else
{
return PathToManagedTool;
}
}
else
{
return PathToNativeTool;
}
return IsManagedTool
? RuntimeHostInfo.GetProcessInfo(PathToManagedToolWithoutExtension, string.Empty).ProcessFilePath
: PathToNativeTool;
}
protected abstract string ToolNameWithoutExtension { get; }
......@@ -80,37 +66,6 @@ protected sealed override string GenerateFullPathToTool()
/// as the implementation of IsManagedTool calls this property. See the comment in
/// <see cref="ManagedCompiler.HasToolBeenOverridden"/>.
/// </remarks>
protected sealed override string ToolName => $"{ToolNameWithoutExtension}.{ToolExtension}";
private static string ToolExtension =>
#if NETCOREAPP2_1
"dll";
#elif NET472
"exe";
#else
#error Unrecognized framework
#endif
private static bool IsCliHost(out string pathToDotnet)
{
#if NETCOREAPP2_1
pathToDotnet = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH");
return !string.IsNullOrEmpty(pathToDotnet);
#elif NET472
pathToDotnet = null;
return false;
#else
#error Unrecognized framework
#endif
}
private static string PrependFileToArgs(string pathToTool, string commandLineArgs)
{
var builder = new CommandLineBuilderExtension();
builder.AppendFileNameIfNotNull(pathToTool);
builder.AppendTextUnquoted(" ");
builder.AppendTextUnquoted(commandLineArgs);
return builder.ToString();
}
protected sealed override string ToolName => $"{ToolNameWithoutExtension}.{RuntimeHostInfo.ToolExtension}";
}
}
......@@ -35,19 +35,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Shared\NamedPipeUtil.cs" />
<Compile Include="..\..\Shared\BuildServerConnection.cs">
<Link>BuildServerConnection.cs</Link>
</Compile>
<Compile Include="..\..\Shared\CoreClrShim.cs">
<Link>CoreClrShim.cs</Link>
</Compile>
<Compile Include="..\..\Shared\BuildServerConnection.cs" Link="BulidServerConnection.cs" />
<Compile Include="..\..\Shared\RuntimeHostInfo.cs" />
<Compile Include="..\Portable\CommitHashAttribute.cs" Link="CommitHashAttribute.cs" />
<Compile Include="..\Portable\InternalUtilities\CommandLineUtilities.cs">
<Link>CommandLineUtilities.cs</Link>
</Compile>
<Compile Include="..\Portable\InternalUtilities\CompilerOptionParseUtilities.cs">
<Link>CompilerOptionParseUtilities.cs</Link>
</Compile>
<Compile Include="..\Portable\InternalUtilities\CommandLineUtilities.cs" Link="CommandLineUtilities.cs" />
<Compile Include="..\Portable\InternalUtilities\CompilerOptionParseUtilities.cs" Link="CompilerOptionParserUtilities.cs" />
<Compile Include="..\Portable\InternalUtilities\IReadOnlySet.cs">
<Link>IReadOnlySet.cs</Link>
</Compile>
......
......@@ -191,49 +191,17 @@ internal static string TryGetAssemblyPath(Assembly assembly)
}
/// <summary>
/// Try to get the directory this assembly is in. Returns null if assembly
/// was in the GAC or DLL location can not be retrieved.
/// Generate the full path to the tool that is deployed with our build tasks.
/// </summary>
public static string GenerateFullPathToTool(string toolName)
internal static string GenerateFullPathToTool(string toolName)
{
string toolLocation = null;
var buildTask = typeof(Utilities).GetTypeInfo().Assembly;
var assemblyPath = TryGetAssemblyPath(buildTask);
if (assemblyPath != null)
{
var assemblyDirectory = Path.GetDirectoryName(assemblyPath);
var desktopToolLocalLocation = Path.Combine(assemblyDirectory, toolName);
var cliToolLocalLocation = Path.Combine(assemblyDirectory, "bincore", toolName);
if (File.Exists(desktopToolLocalLocation))
{
toolLocation = desktopToolLocalLocation;
}
else if (File.Exists(cliToolLocalLocation))
{
toolLocation = cliToolLocalLocation;
}
}
if (toolLocation == null)
{
// Roslyn only deploys to the 32Bit folder of MSBuild, so request this path on all architectures.
var pathToBuildTools = ToolLocationHelper.GetPathToBuildTools(ToolLocationHelper.CurrentToolsVersion, DotNetFrameworkArchitecture.Bitness32);
if (pathToBuildTools != null)
{
var toolMSBuildLocation = Path.Combine(pathToBuildTools, MSBuildRoslynFolderName, toolName);
if (File.Exists(toolMSBuildLocation))
{
toolLocation = toolMSBuildLocation;
}
}
}
var assemblyPath = buildTask.Location;
var assemblyDirectory = Path.GetDirectoryName(assemblyPath);
return toolLocation;
return RuntimeHostInfo.IsDesktopRuntime
? Path.Combine(assemblyDirectory, toolName)
: Path.Combine(assemblyDirectory, "bincore", toolName);
}
}
}
......@@ -36,7 +36,6 @@
</Content>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Shared\CoreClrShim.cs" Link="InternalUtilities\CoreClrShim.cs" />
<Compile Include="..\..\Shared\DesktopShim.cs">
<Link>DesktopShim.cs</Link>
</Compile>
......
......@@ -28,6 +28,7 @@
<PackageReference Include="Microsoft.DiaSymReader.Native" Version="$(MicrosoftDiaSymReaderNativeVersion)"/>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Shared\RuntimeHostInfo.cs" />
<Compile Include="..\..\Shared\NamedPipeUtil.cs" />
<Compile Include="..\..\Shared\BuildClient.cs">
<Link>BuildClient.cs</Link>
......
......@@ -223,7 +223,7 @@ private static DisposableFile GetResultFile(TempDirectory directory, string resu
private static void RunCompilerOutput(TempFile file, string expectedOutput)
{
if (!CoreClrShim.IsRunningOnCoreClr)
if (RuntimeHostInfo.IsDesktopRuntime)
{
var result = ProcessUtilities.Run(file.Path, "", Path.GetDirectoryName(file.Path));
Assert.Equal(expectedOutput.Trim(), result.Output.Trim());
......
......@@ -14,6 +14,7 @@
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CommandLine
{
......@@ -48,14 +49,9 @@ internal abstract class BuildClient
/// </summary>
public static string GetSystemSdkDirectory()
{
if (CoreClrShim.IsRunningOnCoreClr)
{
return null;
}
else
{
return RuntimeEnvironment.GetRuntimeDirectory();
}
return RuntimeHostInfo.IsCoreClrRuntime
? null
: RuntimeEnvironment.GetRuntimeDirectory();
}
/// <summary>
......@@ -236,12 +232,12 @@ private static bool UseNativeArguments()
return false;
}
if (Type.GetType("Mono.Runtime") != null)
if (PlatformInformation.IsRunningOnMono)
{
return false;
}
if (CoreClrShim.IsRunningOnCoreClr)
if (RuntimeHostInfo.IsCoreClrRuntime)
{
// The native invoke ends up giving us both CoreRun and the exe file.
// We've decided to ignore backcompat for CoreCLR,
......
......@@ -56,9 +56,6 @@ internal BuildPathsAlt(string clientDir, string workingDir, string sdkDir, strin
internal sealed class BuildServerConnection
{
internal const string ServerNameDesktop = "VBCSCompiler.exe";
internal const string ServerNameCoreClr = "VBCSCompiler.dll";
// Spend up to 1s connecting to existing process (existing processes should be always responsive).
internal const int TimeOutMsExistingProcess = 1000;
......@@ -374,30 +371,13 @@ internal static bool IsCompilerServerSupported(string tempPath)
internal static bool TryCreateServerCore(string clientDir, string pipeName)
{
string expectedPath;
string processArguments;
#if NETCOREAPP2_1
// The server should be in the same directory as the client
var expectedCompilerPath = Path.Combine(clientDir, ServerNameCoreClr);
expectedPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH") ?? "dotnet";
processArguments = $@"""{expectedCompilerPath}"" ""-pipename:{pipeName}""";
if (!File.Exists(expectedCompilerPath))
{
return false;
}
#elif NET472
// The server should be in the same directory as the client
expectedPath = Path.Combine(clientDir, ServerNameDesktop);
processArguments = $@"""-pipename:{pipeName}""";
var serverPathWithoutExetnsion = Path.Combine(clientDir, "VBCSCompiler");
var serverInfo = RuntimeHostInfo.GetProcessInfo(serverPathWithoutExetnsion, $"-pipename:{pipeName}");
if (!File.Exists(expectedPath))
if (!File.Exists(serverInfo.ToolFilePath))
{
return false;
}
#else
#error Unrecognized configuration
#endif
if (PlatformInformation.IsWindows)
{
......@@ -415,9 +395,9 @@ internal static bool TryCreateServerCore(string clientDir, string pipeName)
PROCESS_INFORMATION processInfo;
Log("Attempting to create process '{0}'", expectedPath);
Log("Attempting to create process '{0}'", serverInfo.ProcessFilePath);
var builder = new StringBuilder($@"""{expectedPath}"" {processArguments}");
var builder = new StringBuilder($@"""{serverInfo.ProcessFilePath}"" {serverInfo.CommandLineArguments}");
bool success = CreateProcess(
lpApplicationName: null,
......@@ -449,8 +429,8 @@ internal static bool TryCreateServerCore(string clientDir, string pipeName)
{
var startInfo = new ProcessStartInfo()
{
FileName = expectedPath,
Arguments = processArguments,
FileName = serverInfo.ProcessFilePath,
Arguments = serverInfo.CommandLineArguments,
UseShellExecute = false,
WorkingDirectory = clientDir,
RedirectStandardInput = true,
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if NETCOREAPP1_1 || NETCOREAPP2_1
#if NETCOREAPP2_1
using System.Diagnostics;
using System.Reflection;
......
......@@ -29,7 +29,7 @@ internal DesktopBuildClient(RequestLanguage language, CompileFunc compileFunc, I
internal static int Run(IEnumerable<string> arguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader)
{
var sdkDir = GetSystemSdkDirectory();
if (CoreClrShim.IsRunningOnCoreClr)
if (RuntimeHostInfo.IsCoreClrRuntime)
{
// Register encodings for console
// https://github.com/dotnet/roslyn/issues/10785
......
// 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.Diagnostics;
using System.IO.Pipes;
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// This type provides information about the runtime which is hosting application. It must be included in a concrete
/// target framework to be used.
/// </summary>
internal static class RuntimeHostInfo
{
internal static bool IsCoreClrRuntime => !IsDesktopRuntime;
internal static string ToolExtension => IsCoreClrRuntime ? "dll" : "exe";
/// <summary>
/// This gets information about invoking a tool on the current runtime. This will attempt to
/// execute a tool as an EXE when on desktop and using dotnet when on CoreClr.
/// </summary>
internal static (string ProcessFilePath, string CommandLineArguments, string ToolFilePath) GetProcessInfo(string toolFilePathWithoutExtension, string commandLineArguments)
{
Debug.Assert(!toolFilePathWithoutExtension.EndsWith(".dll") && !toolFilePathWithoutExtension.EndsWith(".exe"));
var toolFilePath = $"{toolFilePathWithoutExtension}.{ToolExtension}";
if (IsDotnetHost(out string pathToDotNet))
{
commandLineArguments = $@"exec ""{toolFilePath}"" {commandLineArguments}";
return (pathToDotNet, commandLineArguments, toolFilePath);
}
else
{
return (toolFilePath, commandLineArguments, toolFilePath);
}
}
#if NET472
internal static bool IsDesktopRuntime => true;
internal static bool IsDotnetHost(out string pathToDotnet)
{
pathToDotnet = null;
return false;
}
internal static NamedPipeClientStream CreateNamedPipeClient(string serverName, string pipeName, PipeDirection direction, PipeOptions options) =>
new NamedPipeClientStream(serverName, pipeName, direction, options);
#elif NETCOREAPP2_1
internal static bool IsDesktopRuntime => false;
internal static string DotnetHostPathEnvironmentName = "DOTNET_HOST_PATH";
internal static bool IsDotnetHost(out string pathToDotnet)
{
pathToDotnet = GetDotnetPathOrDefault();
return true;
}
/// <summary>
/// Get the path to the dotnet executable. This will throw in the case it is not properly setup
/// by the environment.
/// </summary>
internal static string GetDotnetPath()
{
var pathToDotnet = Environment.GetEnvironmentVariable(DotnetHostPathEnvironmentName);
if (string.IsNullOrEmpty(pathToDotnet))
{
throw new InvalidOperationException($"{DotnetHostPathEnvironmentName} is not set");
}
return pathToDotnet;
}
/// <summary>
/// Get the path to the dotnet executable. In the case the host did not provide this information
/// in the environment this will return simply "dotnet".
/// </summary>
internal static string GetDotnetPathOrDefault()
{
var pathToDotnet = Environment.GetEnvironmentVariable(DotnetHostPathEnvironmentName);
return pathToDotnet ?? "dotnet";
}
#else
#error Unsupported configuration
#endif
}
}
......@@ -891,7 +891,7 @@ public static SyntaxTree ParseWithRoundTripCheck(string text, CSharpParseOptions
string assemblyName = "",
string sourceFileName = "")
{
IEnumerable<MetadataReference> allReferences = CoreClrShim.IsRunningOnCoreClr
IEnumerable<MetadataReference> allReferences = RuntimeUtilities.IsCoreClrRuntime
? TargetFrameworkUtil.NetStandard20References
: TargetFrameworkUtil.Mscorlib461ExtendedReferences.Add(TestReferences.Net461.netstandardRef);
......
......@@ -26,6 +26,7 @@
<PackageReference Include="Microsoft.DiaSymReader.Native" Version="$(MicrosoftDiaSymReaderNativeVersion)"/>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Shared\RuntimeHostInfo.cs" />
<Compile Include="..\..\Shared\NamedPipeUtil.cs" />
<Compile Include="..\..\Shared\BuildClient.cs">
<Link>BuildClient.cs</Link>
......
......@@ -34,6 +34,7 @@
<PackageReference Include="RoslynTools.LightUp.System.Runtime.Loader" Version="$(RoslynToolsLightUpSystemRuntimeLoaderFixedVersion)" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Compilers\Shared\CoreClrShim.cs" />
<Compile Include="..\..\Compilers\Core\Portable\FileSystem\RelativePathResolver.cs">
<Link>Hosting\Resolvers\RelativePathResolver.cs</Link>
</Compile>
......
......@@ -137,7 +137,7 @@ public static class ExecutionConditionUtil
{
public static bool IsWindows => Path.DirectorySeparatorChar == '\\';
public static bool IsUnix => !IsWindows;
public static bool IsDesktop => CoreClrShim.AssemblyLoadContext.Type == null;
public static bool IsDesktop => RuntimeUtilities.IsDesktopRuntime;
public static bool IsWindowsDesktop => IsWindows && IsDesktop;
public static bool IsMonoDesktop => Type.GetType("Mono.Runtime") != null;
public static bool IsCoreClr => !IsDesktop;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册