Permalink
Browse files

Make much of the Workspaces layer Portable.

This change splits the Workspaces layer into two parts, mirroring the Portable/Desktop split that the compilers did. The core parts of the Workspaces layer (managing documents and projects, formatting, some refactoring, code fixes) is kept in the portable subset, with a few non-portable pieces remaining, notably MSBuild support.

This change has a major impact on how MEF now works in Roslyn. Traditional MEF (“MEFv1”) is not portable, and so we must move the Workspaces layer over to using the Microsoft.Composition NuGet package (“MEFv2”) which is. The APIs are distinct in that each has its own namespace, but the concepts are more or less identical. It requires some care though: the workspaces layer is simple in that it only references MEFv2, but higher layers have to reference both versions to use metadata attributes. Exports using metadata attributes from the editor (say, ContentTypeAttribute) must use MEFv1 attributes to export, whereas exports for the workspaces layer must use MEFv2 attributes. The rule is subtle and yet simple, and so a diagnostic is provided which catches any offenses to prevent confusion.

This also has some impact in how we create MEF hosts: if you wish to host just the base workspaces layer, we can use MEFv2 to compose everything. The HostServices implementation (MefV1HostServices) that consumes a MEFv1 ExportProvider. If you’re in Visual Studio, you can use this implementation to get the full set of host services provided in Visual Studio.

Otherwise, most of the changes in here are minor: we react to some APIs that have been moved/renamed in the portable subset we are targeting, and also align our various exception helper utilities with the compiler’s precedent. (changeset 1349276)
  • Loading branch information...
jasonmalinowski committed Oct 7, 2014
1 parent d0ea086 commit e76a29a4ad62d5b20a982388cbc9e9b2d9f70e48
Showing 1,855 changed files with 98,258 additions and 57,600 deletions.
@@ -295,7 +295,7 @@ private Task CompileNamespaceAsTask(NamespaceSymbol symbol)
CompileNamespace(symbol);
return (object)null;
}
catch (Exception e) if (CompilerFatalError.ReportUnlessCanceled(e))
catch (Exception e) if (FatalError.ReportUnlessCanceled(e))
{
throw ExceptionUtilities.Unreachable;
}
@@ -342,7 +342,7 @@ private Task CompileNamedTypeAsTask(NamedTypeSymbol symbol)
CompileNamedType(symbol);
return (object)null;
}
catch (Exception e) if (CompilerFatalError.Report(e))
catch (Exception e) if (FatalError.Report(e))
{
throw ExceptionUtilities.Unreachable;
}
@@ -21,7 +21,7 @@ internal Csc(string responseFile, string baseDirectory, string[] args)
internal static int Run(string[] args)
{
CompilerFatalError.Handler = FailFast.OnFatalException;
FatalError.Handler = FailFast.OnFatalException;
Csc compiler = new Csc(CSharpResponseFileName, Directory.GetCurrentDirectory(), args);
@@ -221,7 +221,7 @@
<Compile Include="Instrumentation\RoslynCompilerEventSource.cs" />
<Compile Include="InternalUtilities\ArrayExtensions.cs" />
<Compile Include="InternalUtilities\BitArithmeticUtilities.cs" />
<Compile Include="InternalUtilities\CompilerFatalError.cs" />
<Compile Include="InternalUtilities\FatalError.cs" />
<Compile Include="InternalUtilities\ComStreamWrapper.cs" />
<Compile Include="InternalUtilities\ConcurrentDictionaryExtensions.cs" />
<Compile Include="InternalUtilities\ConcurrentLruCache.cs" />
@@ -269,7 +269,6 @@
<Compile Include="InternalUtilities\SuppressUnmanagedCodeSecurityAttribute.cs" />
<Compile Include="InternalUtilities\TextChangeRangeExtensions.cs" />
<Compile Include="InternalUtilities\TextKeyedCache.cs" />
<Compile Include="InternalUtilities\ThreadingUtilities.cs" />
<Compile Include="InternalUtilities\ThreadSafeFlagOperations.cs" />
<Compile Include="InternalUtilities\ThreeState.cs" />
<Compile Include="InternalUtilities\ValueTuple.cs" />
@@ -16,13 +16,8 @@ namespace Microsoft.CodeAnalysis.Instrumentation
/// <summary>
/// This EventSource exposes our events to ETW.
/// RoslynCompilerEventSource GUID is {9f93daf9-7fee-5301-ebea-643b538889b4}.
/// CodeSense.RoslynCompilerEventSource GUID is {08e567fa-f66d-52c7-4e58-d802264cc8db}.
/// </summary>
#if CODESENSE
[EventSource(Name = "CodeSense.RoslynCompilerEventSource")]
#else
[EventSource(Name = "RoslynCompilerEventSource")]
#endif
internal sealed class RoslynCompilerEventSource : EventSource
{
// We might not be "enabled" but we always have this singleton alive.
@@ -1,82 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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;
namespace Microsoft.CodeAnalysis
{
internal static class CompilerFatalError
{
private static Action<Exception> handler;
// Set by the host to a fail fast trigger,
// if the host desires to crash the process on a fatal exception.
// May also just report a non-fatal Watson and continue.
public static Action<Exception> Handler
{
get
{
return handler;
}
set
{
if (handler != value)
{
Debug.Assert(handler == null, "Handler already set");
handler = value;
}
}
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Unless the exception is <see cref="OperationCanceledException"/>
/// it calls <see cref="Handler"/>. The exception is passed thru (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool ReportUnlessCanceled(Exception exception)
{
if (exception is OperationCanceledException)
{
return false;
}
return Report(exception);
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Unless the exception is <see cref="NotImplementedException"/>
/// it calls <see cref="Handler"/>. The exception is passed thru (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool ReportUnlessNotImplemented(Exception exception)
{
if (exception is NotImplementedException)
{
return false;
}
return Report(exception);
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Calls <see cref="Handler"/> and passes the exception thru (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool Report(Exception exception)
{
var localHandler = handler;
if (localHandler != null)
{
localHandler(exception);
}
return false;
}
}
}
@@ -0,0 +1,89 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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;
namespace Microsoft.CodeAnalysis
{
internal static class FatalError
{
private static Action<Exception> handler;
private static Exception reportedException;
private static string reportedExceptionMessage;
// Set by the host to a fail fast trigger,
// if the host desires to crash the process on a fatal exception.
// May also just report a non-fatal Watson and continue.
public static Action<Exception> Handler
{
get
{
return handler;
}
set
{
if (handler != value)
{
Debug.Assert(handler == null, "Handler already set");
handler = value;
}
}
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Unless the exception is <see cref="OperationCanceledException"/>
/// it calls <see cref="Handler"/>. The exception is passed thru (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool ReportUnlessCanceled(Exception exception)
{
if (exception is OperationCanceledException)
{
return false;
}
return Report(exception);
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Unless the exception is <see cref="NotImplementedException"/>
/// it calls <see cref="Handler"/>. The exception is passed thru (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool ReportUnlessNotImplemented(Exception exception)
{
if (exception is NotImplementedException)
{
return false;
}
return Report(exception);
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Calls <see cref="Handler"/> and passes the exception thru (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool Report(Exception exception)
{
// hold onto last exception to make investigation easier
reportedException = exception;
reportedExceptionMessage = exception.ToString();
var localHandler = handler;
if (localHandler != null)
{
localHandler(exception);
}
return false;
}
}
}
@@ -1,17 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
namespace Microsoft.CodeAnalysis
{
internal static class ThreadingUtilities
{
private static int threadIdDispenser;
private static ThreadLocal<int> currentThreadId = new ThreadLocal<int>(() => Interlocked.Increment(ref threadIdDispenser));
internal static int GetCurrentThreadId()
{
return currentThreadId.Value;
}
}
}
@@ -102,7 +102,7 @@ public async Task ServeConnection()
{
return handler.HandleRequest(request, cancellationTokenSource.Token);
}
catch (Exception e) if (CompilerFatalError.ReportUnlessCanceled(e))
catch (Exception e) if (FatalError.ReportUnlessCanceled(e))
{
throw ExceptionUtilities.Unreachable;
}
@@ -76,7 +76,7 @@ public static int Main(string[] args)
CompilerServerLogger.LogException(e, "Could not read AppSettings");
}
CompilerFatalError.Handler = FailFast.OnFatalException;
FatalError.Handler = FailFast.OnFatalException;
var dispatcher = new ServerDispatcher(BuildProtocolConstants.PipeName,
new CompilerRequestHandler(),
@@ -263,7 +263,7 @@ private async Task DispatchConnection(NamedPipeServerStream pipeStream)
}
ConnectionCompleted();
}
catch (Exception e) if (CompilerFatalError.Report(e))
catch (Exception e) if (FatalError.Report(e))
{
throw ExceptionUtilities.Unreachable;
}
@@ -43,7 +43,6 @@
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<DefineConstants>PERFORMANCE_DIAGNOSTICS</DefineConstants>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<Optimize>false</Optimize>
<DebugType>full</DebugType>
@@ -52,7 +51,6 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<DefineTrace>true</DefineTrace>
<DefineConstants>PERFORMANCE_DIAGNOSTICS</DefineConstants>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
@@ -54,7 +54,6 @@
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<DefineConstants>PERFORMANCE_DIAGNOSTICS</DefineConstants>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<Optimize>false</Optimize>
<DebugType>full</DebugType>
@@ -63,7 +62,6 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<DefineTrace>true</DefineTrace>
<DefineConstants>PERFORMANCE_DIAGNOSTICS</DefineConstants>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
@@ -245,10 +245,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If Not _frozen Then
' First time we're called, get the thread id. Subsequent times, check it hasn't changed.
If _threadIdForDeclaration = -1 Then
Interlocked.CompareExchange(_threadIdForDeclaration, ThreadingUtilities.GetCurrentThreadId(), -1)
Interlocked.CompareExchange(_threadIdForDeclaration, Environment.CurrentManagedThreadId, -1)
End If
Debug.Assert(_threadIdForDeclaration = ThreadingUtilities.GetCurrentThreadId())
Debug.Assert(_threadIdForDeclaration = Environment.CurrentManagedThreadId)
End If
End Sub
#End If
@@ -455,7 +455,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Sub()
Try
CompileNamespace(symbol)
Catch e As Exception When CompilerFatalError.ReportUnlessCanceled(e)
Catch e As Exception When FatalError.ReportUnlessCanceled(e)
Throw ExceptionUtilities.Unreachable
End Try
End Sub,
@@ -487,7 +487,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Sub()
Try
CompileNamedType(symbol, filter)
Catch e As Exception When CompilerFatalError.ReportUnlessCanceled(e)
Catch e As Exception When FatalError.ReportUnlessCanceled(e)
Throw ExceptionUtilities.Unreachable
End Try
End Sub,
@@ -1743,7 +1743,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Private Function BuildMembersAndInitializers(diagBag As DiagnosticBag) As MembersAndInitializers
#If DEBUG Then
Dim threadId = ThreadingUtilities.GetCurrentThreadId()
Dim threadId = Environment.CurrentManagedThreadId
Debug.Assert(m_computingMembersThreadId <> threadId)
Interlocked.CompareExchange(m_computingMembersThreadId, threadId, 0)
#End If
@@ -683,7 +683,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Sub()
Try
visitor(symbol)
Catch e As Exception When CompilerFatalError.ReportUnlessCanceled(e)
Catch e As Exception When FatalError.ReportUnlessCanceled(e)
Throw ExceptionUtilities.Unreachable
End Try
End Sub,
@@ -18,7 +18,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CommandLine
Dim compiler = New Vbc(BasicResponseFileName, Directory.GetCurrentDirectory(), args)
CompilerFatalError.Handler = AddressOf FailFast.OnFatalException
FatalError.Handler = AddressOf FailFast.OnFatalException
' We store original encoding and restore it later to revert
' the changes that might be done by /utf8output options
Oops, something went wrong.

0 comments on commit e76a29a

Please sign in to comment.