diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/ForegroundDispatcher.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ForegroundDispatcher.cs new file mode 100644 index 0000000000..e9f9ca61eb --- /dev/null +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/ForegroundDispatcher.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. 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.Runtime.CompilerServices; +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.CodeAnalysis.Razor +{ + internal abstract class ForegroundDispatcher : IWorkspaceService + { + public abstract bool IsForegroundThread { get; } + + public virtual void AssertForegroundThread([CallerMemberName] string caller = null) + { + if (!IsForegroundThread) + { + caller = caller == null ? Workspaces.Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'"; + throw new InvalidOperationException(Workspaces.Resources.FormatForegroundDispatcher_AssertForegroundThread(caller)); + } + } + + public virtual void AssertBackgroundThread([CallerMemberName] string caller = null) + { + if (IsForegroundThread) + { + caller = caller == null ? Workspaces.Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'"; + throw new InvalidOperationException(Workspaces.Resources.FormatForegroundDispatcher_AssertBackgroundThread(caller)); + } + } + } +} diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/Resources.Designer.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..058b78c6ed --- /dev/null +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/Resources.Designer.cs @@ -0,0 +1,86 @@ +// +namespace Microsoft.CodeAnalysis.Razor.Workspaces +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class Resources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.CodeAnalysis.Razor.Workspaces.Resources", typeof(Resources).GetTypeInfo().Assembly); + + /// + /// Value cannot be null or an empty string. + /// + internal static string ArgumentCannotBeNullOrEmpty + { + get => GetString("ArgumentCannotBeNullOrEmpty"); + } + + /// + /// Value cannot be null or an empty string. + /// + internal static string FormatArgumentCannotBeNullOrEmpty() + => GetString("ArgumentCannotBeNullOrEmpty"); + + /// + /// {0} must be called on a background thread. + /// + internal static string ForegroundDispatcher_AssertBackgroundThread + { + get => GetString("ForegroundDispatcher_AssertBackgroundThread"); + } + + /// + /// {0} must be called on a background thread. + /// + internal static string FormatForegroundDispatcher_AssertBackgroundThread(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertBackgroundThread"), p0); + + /// + /// {0} must be called on the foreground thread. + /// + internal static string ForegroundDispatcher_AssertForegroundThread + { + get => GetString("ForegroundDispatcher_AssertForegroundThread"); + } + + /// + /// {0} must be called on the foreground thread. + /// + internal static string FormatForegroundDispatcher_AssertForegroundThread(object p0) + => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertForegroundThread"), p0); + + /// + /// The method + /// + internal static string ForegroundDispatcher_NoMethodNamePlaceholder + { + get => GetString("ForegroundDispatcher_NoMethodNamePlaceholder"); + } + + /// + /// The method + /// + internal static string FormatForegroundDispatcher_NoMethodNamePlaceholder() + => GetString("ForegroundDispatcher_NoMethodNamePlaceholder"); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources.resx b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources.resx new file mode 100644 index 0000000000..fca5a30e15 --- /dev/null +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Resources.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Value cannot be null or an empty string. + + + {0} must be called on a background thread. + + + {0} must be called on the foreground thread. + + + The method + + \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs index 106efbca51..6bbd900efd 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/Editor/VisualStudioRazorParser.cs @@ -5,6 +5,7 @@ using System; using System.Timers; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.CodeAnalysis.Razor; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/ForegroundDispatcher.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/ForegroundDispatcher.cs deleted file mode 100644 index 712cf635a6..0000000000 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/ForegroundDispatcher.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation. 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.Runtime.CompilerServices; - -namespace Microsoft.VisualStudio.LanguageServices.Razor -{ - internal abstract class ForegroundDispatcher - { - public abstract bool IsForegroundThread { get; } - - public virtual void AssertForegroundThread([CallerMemberName] string caller = null) - { - if (!IsForegroundThread) - { - caller = caller == null ? Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'"; - throw new InvalidOperationException(Resources.FormatForegroundDispatcher_AssertForegroundThread(caller)); - } - } - - public virtual void AssertBackgroundThread([CallerMemberName] string caller = null) - { - if (IsForegroundThread) - { - caller = caller == null ? Resources.ForegroundDispatcher_NoMethodNamePlaceholder : $"'{caller}'"; - throw new InvalidOperationException(Resources.FormatForegroundDispatcher_AssertBackgroundThread(caller)); - } - } - } -} diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs index f137c477f1..2237686c54 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/Properties/Resources.Designer.cs @@ -24,48 +24,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor internal static string FormatArgumentCannotBeNullOrEmpty() => GetString("ArgumentCannotBeNullOrEmpty"); - /// - /// {0} must be called on a background thread. - /// - internal static string ForegroundDispatcher_AssertBackgroundThread - { - get => GetString("ForegroundDispatcher_AssertBackgroundThread"); - } - - /// - /// {0} must be called on a background thread. - /// - internal static string FormatForegroundDispatcher_AssertBackgroundThread(object p0) - => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertBackgroundThread"), p0); - - /// - /// {0} must be called on the foreground thread. - /// - internal static string ForegroundDispatcher_AssertForegroundThread - { - get => GetString("ForegroundDispatcher_AssertForegroundThread"); - } - - /// - /// {0} must be called on the foreground thread. - /// - internal static string FormatForegroundDispatcher_AssertForegroundThread(object p0) - => string.Format(CultureInfo.CurrentCulture, GetString("ForegroundDispatcher_AssertForegroundThread"), p0); - - /// - /// The method - /// - internal static string ForegroundDispatcher_NoMethodNamePlaceholder - { - get => GetString("ForegroundDispatcher_NoMethodNamePlaceholder"); - } - - /// - /// The method - /// - internal static string FormatForegroundDispatcher_NoMethodNamePlaceholder() - => GetString("ForegroundDispatcher_NoMethodNamePlaceholder"); - /// /// An unexpected exception occurred when invoking '{0}.{1}' on the Razor language service. /// diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx b/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx index 3dfcb98b6f..87f559339f 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/Resources.resx @@ -120,15 +120,6 @@ Value cannot be null or an empty string. - - {0} must be called on a background thread. - - - {0} must be called on the foreground thread. - - - The method - An unexpected exception occurred when invoking '{0}.{1}' on the Razor language service. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs index 1a8ab11930..72e27447a5 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/VisualStudioForegroundDispatcher.cs @@ -1,12 +1,15 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.ComponentModel.Composition; +using System.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Razor; using Microsoft.VisualStudio.Shell; namespace Microsoft.VisualStudio.LanguageServices.Razor { - [Export(typeof(ForegroundDispatcher))] + [Shared] + [ExportWorkspaceService(typeof(ForegroundDispatcher), ServiceLayer.Host)] internal class VisualStudioForegroundDispatcher : ForegroundDispatcher { public override bool IsForegroundThread => ThreadHelper.CheckAccess(); diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs index dbe8bbdae0..3c7d626984 100644 --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/ForegroundDispatcherTestBase.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading; +using Microsoft.CodeAnalysis.Razor; namespace Microsoft.VisualStudio.LanguageServices.Razor {