提交 514ab614 编写于 作者: J Jared Parsons

Use multi-targeting to control compilation helpers

This changes our core Roslyn.Test.Utilities project to use
multi-targeting to control how we create our core compilation helper.
Previously this was done by having a separate runtime specific assembly
which was probed at runtime.

The intent of this change is to make our build more correct here. I can
now target just Roslyn.Test.Utilties with a net46 framework and get a
runnable asset out of it. This is necessary in order for our unit tests
to successfully run when moved to multi-target.

Presently this makes it multi-target across net46, netcoreapp2.0 and
netstandard1.3. The impl in netstandard 1.3 simply throw for this
specific API. Over the long term it make make sense to pull this out to
a separate library that only targets net46 + netcoreapp2.0. That
requires a much deeper investment in multi-targeting though. Decided to
start smaller for now.
上级 8c8a8c0b
......@@ -100,7 +100,7 @@
<!-- The netstandard 1.3 package by default includes Microsoft.CodeAnalysis. That's a bit
of a non-starter since we build it. Using manual references for now -->
<DisableImplicitFrameworkReferences Condition="'$(DisableImplicitFrameworkReferences)' == ''" >true</DisableImplicitFrameworkReferences>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendTargetFrameworkToOutputPath Condition="'$(TargetFrameworks)' == ''">false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<!-- Only generate our runtimeconfig.json files for net core apps. It's unnecessary in desktop projects
......
......@@ -19,6 +19,8 @@
<UseRoslynAnalyzers Condition="!Exists('$(NuGetPackageRoot)\Microsoft.CodeQuality.Analyzers\$(RoslynDiagnosticsNugetPackageVersion)\analyzers\dotnet\cs\Analyzer.Utilities.dll')">False</UseRoslynAnalyzers>
<RoslynDiagnosticsPropsFilePath>$(NuGetPackageRoot)/microsoft.net.roslyndiagnostics/$(RoslynDiagnosticsNugetPackageVersion)/roslyn/Microsoft.Net.RoslynDiagnostics.props</RoslynDiagnosticsPropsFilePath>
<RoslynRuntimeIdentifier Condition="'$(RoslynRuntimeIdentifier)' == '' AND '$(OS)' == 'Windows_NT'">win7-x64</RoslynRuntimeIdentifier>
<RoslynPortableTargetFrameworks>net46;netcoreapp2.0</RoslynPortableTargetFrameworks>
<Features>strict,IOperation</Features>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<SignAssembly>true</SignAssembly>
......@@ -106,6 +108,12 @@
<!-- Unix specific settings -->
<PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
<RoslynDebugType>portable</RoslynDebugType>
<!-- Presently can't build anything with a net46 TargetFramework on non-Windows. Disabling
for now.
https://github.com/dotnet/roslyn/issues/20932 -->
<RoslynPortableTargetFrameworks>netcoreapp2.0</RoslynPortableTargetFrameworks>
</PropertyGroup>
<!--
......
......@@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Test.Utilities.Desktop;
using Roslyn.Utilities;
using Xunit;
......
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities.Desktop;
using Roslyn.Utilities;
using Xunit;
......
......@@ -6,6 +6,7 @@
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Test.Utilities.Desktop;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols
......
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Test.Utilities.Desktop;
using Roslyn.Utilities;
using Xunit;
......
' 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 Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
......
......@@ -2,6 +2,7 @@
Imports System.Reflection
Imports Roslyn.Test.Utilities
Imports Roslyn.Test.Utilities.Desktop
Imports Xunit
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
......
......@@ -9,6 +9,7 @@ Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Imports Roslyn.Test.Utilities
Imports Roslyn.Test.Utilities.Desktop
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
......
......@@ -19,7 +19,7 @@
</dependencies>
</metadata>
<files>
<file src="Dlls\TestUtilities\Roslyn.Test.Utilities.dll" target="lib\net46" />
<file src="Dlls\TestUtilities\net46\Roslyn.Test.Utilities.dll" target="lib\net46" />
<file src="Dlls\VisualStudioIntegrationTestUtilities\Microsoft.VisualStudio.IntegrationTest.Utilities.dll" target="lib\net46" />
<file src="Dlls\ServicesTestUtilities\Roslyn.Services.Test.Utilities.dll" target="lib\net46" />
</files>
......
......@@ -858,7 +858,7 @@ Public Class BuildDevDivInsertionFiles
add("Dlls\ServicesTestUtilities\Roslyn.Services.Test.Utilities.dll")
add("Dlls\PdbUtilities\Roslyn.Test.PdbUtilities.dll")
add("Dlls\TestUtilities.Desktop\Roslyn.Test.Utilities.Desktop.dll")
add("Dlls\TestUtilities\Roslyn.Test.Utilities.dll")
add("Dlls\TestUtilities\net46\Roslyn.Test.Utilities.dll")
add("UnitTests\EditorServicesTest\BasicUndo.dll")
add("UnitTests\EditorServicesTest\Moq.dll")
add("UnitTests\EditorServicesTest\Microsoft.CodeAnalysis.Test.Resources.Proprietary.dll")
......
......@@ -27,20 +27,13 @@ internal static IRuntimeEnvironment Create(IEnumerable<ModuleData> additionalDep
private static IRuntimeEnvironmentFactory GetFactoryImplementation()
{
string assemblyName;
string typeName;
if (CoreClrShim.IsRunningOnCoreClr)
{
assemblyName = "Roslyn.Test.Utilities.CoreClr";
typeName = "Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime.CoreCLRRuntimeEnvironmentFactory";
}
else
{
assemblyName = "Roslyn.Test.Utilities.Desktop";
typeName = "Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime.DesktopRuntimeEnvironmentFactory";
}
return RuntimeUtilities.GetFactoryImplementation<IRuntimeEnvironmentFactory>(assemblyName, typeName);
#if NET46
return new Roslyn.Test.Utilities.Desktop.DesktopRuntimeEnvironmentFactory();
#elif NETCOREAPP2_0
return new Roslyn.Test.Utilities.CoreClr.CoreCLRRuntimeEnvironmentFactory();
#else
throw new NotSupportedException();
#endif
}
public static void CaptureOutput(Action action, int expectedLength, out string output, out string errorOutput)
......@@ -73,26 +66,6 @@ private static IEnumerable<ModuleMetadata> EnumerateModules(Metadata metadata)
return (metadata.Kind == MetadataImageKind.Assembly) ? ((AssemblyMetadata)metadata).GetModules().AsEnumerable() : SpecializedCollections.SingletonEnumerable((ModuleMetadata)metadata);
}
/// <summary>
/// Loads the given assembly name, assuming the same public key, culture, version,
/// and architecture as this assembly, and uses reflection to instantiate the given
/// type and return the value.
/// </summary>
internal static T GetFactoryImplementation<T>(string assemblyName, string typeName)
{
var thisAssemblyName = typeof(RuntimeUtilities).GetTypeInfo().Assembly.GetName();
var name = new AssemblyName();
name.Name = assemblyName;
name.Version = thisAssemblyName.Version;
name.SetPublicKey(thisAssemblyName.GetPublicKey());
name.CultureName = thisAssemblyName.CultureName;
name.ProcessorArchitecture = thisAssemblyName.ProcessorArchitecture;
var assembly = Assembly.Load(name);
var type = assembly.GetType(typeName);
return (T)Activator.CreateInstance(type);
}
/// <summary>
/// Emit all of the references which are not directly or indirectly a <see cref="Compilation"/> value.
/// </summary>
......
......@@ -15,7 +15,7 @@
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities
namespace Roslyn.Test.Utilities
{
public struct ModuleDataId
{
......
// 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 NETCOREAPP2_0
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime;
using Roslyn.Test.Utilities;
using static Roslyn.Test.Utilities.RuntimeUtilities;
namespace Microsoft.CodeAnalysis.Test.Utilities
namespace Roslyn.Test.Utilities.CoreClr
{
public class CoreCLRRuntimeEnvironment : IRuntimeEnvironment, IInternalRuntimeEnvironment
{
......@@ -159,3 +158,4 @@ private sealed class EmitData
}
}
}
#endif
// 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 NETCOREAPP2_0
using System;
using System.Collections.Generic;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.CoreClr
{
public sealed class CoreCLRRuntimeEnvironmentFactory : IRuntimeEnvironmentFactory
{
......@@ -12,3 +14,4 @@ public IRuntimeEnvironment Create(IEnumerable<ModuleData> additionalDependencies
=> new CoreCLRRuntimeEnvironment(additionalDependencies);
}
}
#endif
using System;
#if NETCOREAPP2_0
using System;
using System.IO;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities
namespace Roslyn.Test.Utilities.CoreClr
{
internal static class SharedConsole
{
......@@ -70,3 +73,5 @@ private abstract class SharedConsoleWriter : TextWriter
}
}
}
#endif
// 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 NETCOREAPP2_0
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
......@@ -14,7 +14,7 @@
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.CoreClr
{
internal sealed class TestExecutionLoadContext : AssemblyLoadContext
{
......@@ -174,3 +174,4 @@ private static bool TryGetAssemblyName(string filePath, out string name)
}
}
}
#endif
// 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 NET46
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
......@@ -9,7 +11,7 @@
using System.Threading.Tasks;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.Desktop
{
/// <summary>
/// This is a singleton per AppDomain which manages all of the assemblies which were ever loaded into it.
......@@ -117,3 +119,4 @@ private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
}
}
}
#endif
// 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 NET46
using System;
using System.IO;
using System.Reflection;
namespace Microsoft.CodeAnalysis.Test.Utilities
namespace Roslyn.Test.Utilities.Desktop
{
public static class AppDomainUtils
{
......@@ -52,3 +52,4 @@ private static Assembly OnResolve(object sender, ResolveEventArgs e)
}
}
}
#endif
// 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 NET46
using System;
using System.Collections.Generic;
......@@ -9,11 +10,10 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.CodeAnalysis.Test.Utilities.ComTypes;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities.Desktop.ComTypes;
namespace Microsoft.CodeAnalysis.Test.Utilities
namespace Roslyn.Test.Utilities.Desktop
{
public static class CLRHelpers
{
......@@ -340,3 +340,5 @@ public enum CorOpenFlags : uint
};
}
}
#endif
// 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 NET46
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
......@@ -10,11 +12,12 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using static Roslyn.Test.Utilities.RuntimeUtilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.Desktop
{
public sealed class DesktopRuntimeEnvironment : IDisposable, IRuntimeEnvironment, IInternalRuntimeEnvironment
{
......@@ -121,13 +124,6 @@ private RuntimeData CreateAndInitializeRuntimeData(IEnumerable<ModuleData> compi
private static RuntimeData GetOrCreateRuntimeData(IEnumerable<ModuleData> modules)
{
// Mono doesn't support AppDomains to the degree we use them for our tests and as a result many of
// the checks are disabled. Create an instance in this domain since it's not actually used.
if (MonoHelpers.IsRunningOnMono())
{
return new RuntimeData(new RuntimeAssemblyManager(), null);
}
var data = TryGetCachedRuntimeData(modules);
if (data != null)
{
......@@ -401,3 +397,4 @@ internal static void Capture(Action action, int expectedLength, out string outpu
Capture(action, expectedLength, out output, out errorOutput);
}
}
#endif
using System.Collections.Generic;
#if NET46
using System.Collections.Generic;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.Desktop
{
public sealed class DesktopRuntimeEnvironmentFactory : IRuntimeEnvironmentFactory
{
......@@ -11,3 +12,5 @@ public IRuntimeEnvironment Create(IEnumerable<ModuleData> additionalDependencies
}
}
}
#endif
using System;
#if NET46
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
......@@ -13,7 +14,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Test.Utilities;
namespace Roslyn.Test.Utilities
namespace Roslyn.Test.Utilities.Desktop
{
public static class DesktopRuntimeUtil
{
......@@ -94,3 +95,5 @@ internal static Assembly LoadAsAssembly(string moduleName, ImmutableArray<byte>
}
}
#endif
// 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 NET46
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Microsoft.CodeAnalysis;
using static Roslyn.Test.Utilities.ExceptionHelper;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.Desktop
{
[Serializable]
public class RuntimePeVerifyException : Exception
......@@ -36,3 +37,4 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
}
}
}
#endif
// 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 NET46
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
......@@ -16,7 +17,7 @@
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities
namespace Roslyn.Test.Utilities.Desktop
{
internal static class SerializationInfoExtensions
{
......@@ -49,3 +50,5 @@ public static ImmutableArray<byte> GetByteArray(this SerializationInfo info, str
}
}
}
#endif
// 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 NET46
using System;
using System.Collections.Generic;
using System.Globalization;
......@@ -9,7 +9,7 @@
using System.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities
namespace Roslyn.Test.Utilities.Desktop
{
public class MetadataSignatureHelper
{
......@@ -683,3 +683,5 @@ static public IEnumerable<string> GetMemberSignatures(System.Reflection.Assembly
}
}
}
#endif
// 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 NET46
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
......@@ -7,9 +8,11 @@
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.Desktop
{
internal sealed class RuntimeAssemblyManager : MarshalByRefObject, IDisposable
{
......@@ -70,7 +73,7 @@ public RuntimeAssemblyManager()
var currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += AssemblyResolve;
currentDomain.AssemblyLoad += AssemblyLoad;
CLRHelpers.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolve;
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolve;
_preloadedSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var assembly in currentDomain.GetAssemblies())
......@@ -91,7 +94,7 @@ public void Dispose()
// clean up our handlers, so that they don't accumulate
AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolve;
AppDomain.CurrentDomain.AssemblyLoad -= AssemblyLoad;
CLRHelpers.ReflectionOnlyAssemblyResolve -= ReflectionOnlyAssemblyResolve;
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= ReflectionOnlyAssemblyResolve;
foreach (var assembly in _loadedAssemblies)
{
......@@ -448,3 +451,5 @@ public string[] PeVerifyModules(string[] modulesToVerify, bool throwOnError = tr
}
}
}
#endif
// 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 NET46
using System;
using System.Collections.Concurrent;
......@@ -16,7 +17,7 @@
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
namespace Roslyn.Test.Utilities.Desktop
{
[Serializable]
public struct RuntimeModuleDataId : ISerializable
......@@ -74,3 +75,5 @@ public void GetObjectData(SerializationInfo info, StreamingContext context)
}
}
}
#endif
......@@ -9,7 +9,7 @@
<AssemblyName>Roslyn.Test.Utilities</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nonshipping>true</Nonshipping>
<TargetFramework>netstandard1.3</TargetFramework>
<TargetFrameworks>netstandard1.3;$(RoslynPortableTargetFrameworks)</TargetFrameworks>
<DefineConstants>$(DefineConstants);DNX</DefineConstants>
<NoStdLib>true</NoStdLib>
<RootNamespace></RootNamespace>
......@@ -103,6 +103,7 @@
<PackageReference Include="System.Threading.Thread" Version="$(SystemThreadingThreadVersion)" />
<PackageReference Include="System.Xml.XDocument" Version="$(SystemXmlXDocumentVersion)" />
<PackageReference Include="System.Xml.XmlDocument" Version="$(SystemXmlXmlDocumentVersion)" />
<PackageReference Include="System.Runtime.Loader" Version="$(SystemRuntimeLoaderVersion)" Condition="'$(TargetFramework)' == 'netcoreapp2.0'" />
<PackageReference Include="xunit" Version="$(xunitVersion)" />
<PackageReference Include="xunit.analyzers" Version="$(xunitanalyzersVersion)" />
<PackageReference Include="xunit.runner.console" Version="$(xunitrunnerconsoleVersion)" />
......
......@@ -17,7 +17,10 @@ internal class ProjectUtil
internal XmlNamespaceManager Manager { get; }
internal XNamespace Namespace { get; }
public bool IsNewSdk => Document.XPathSelectElements("//mb:TargetFramework", Manager).FirstOrDefault() != null;
public bool IsNewSdk =>
Document.XPathSelectElements("//mb:TargetFramework", Manager).FirstOrDefault() != null ||
Document.XPathSelectElements("//mb:TargetFrameworks", Manager).FirstOrDefault() != null;
public bool IsDesktopProject => Document.XPathSelectElements("//mb:TargetFrameworkVersion", Manager).FirstOrDefault() != null;
public bool IsPclProject
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册