Merge remote-tracking branch 'origin/main-vs-deps' into main

This commit is contained in:
N. Taylor Mullen 2021-08-04 12:40:35 -07:00
Родитель 7bf859f430 ddecbfd9ea
Коммит 0d1ac4c5ba
295 изменённых файлов: 3180 добавлений и 2677 удалений

Просмотреть файл

@ -19,6 +19,7 @@
<FileSignInfo Include="OmniSharp.Extensions.LanguageProtocol.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="OmniSharp.Extensions.LanguageServer.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="OmniSharp.Extensions.LanguageServer.Shared.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="Nerdbank.Streams.dll" CertificateName="3PartySHA2" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -91,7 +91,7 @@
<Tooling_MicrosoftCodeAnalysisTestingVersion>1.0.1-beta1.21103.2</Tooling_MicrosoftCodeAnalysisTestingVersion>
<MicrosoftVisualStudioShellPackagesVersion>17.0.0-previews-1-31410-258</MicrosoftVisualStudioShellPackagesVersion>
<MicrosoftVisualStudioPackagesVersion>17.0.35-gdeb9415fdc</MicrosoftVisualStudioPackagesVersion>
<RoslynPackageVersion>4.0.0-2.21354.7</RoslynPackageVersion>
<RoslynPackageVersion>4.0.0-3.21367.2</RoslynPackageVersion>
</PropertyGroup>
<PropertyGroup Label="Manual">
<MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>5.0.0-preview.4.20205.1</MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>
@ -106,7 +106,7 @@
<MicrosoftVisualStudioEditorPackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioEditorPackageVersion>
<MicrosoftVisualStudioLanguagePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguagePackageVersion>
<MicrosoftVisualStudioLanguageIntellisensePackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioLanguageIntellisensePackageVersion>
<MicrosoftVisualStudioLanguageServerClientImplementationPackageVersion>17.0.2062-g973d339867</MicrosoftVisualStudioLanguageServerClientImplementationPackageVersion>
<MicrosoftVisualStudioLanguageServerClientImplementationPackageVersion>17.0.3094-g82ddffa096</MicrosoftVisualStudioLanguageServerClientImplementationPackageVersion>
<MicrosoftVisualStudioLiveSharePackageVersion>0.3.1074</MicrosoftVisualStudioLiveSharePackageVersion>
<MicrosoftVisualStudioProjectSystemSDKPackageVersion>16.10.81-pre</MicrosoftVisualStudioProjectSystemSDKPackageVersion>
<MicrosoftVisualStudioShell150PackageVersion>$(MicrosoftVisualStudioShellPackagesVersion)</MicrosoftVisualStudioShell150PackageVersion>
@ -132,6 +132,7 @@
<Tooling_MicrosoftCodeAnalysisAnalyzersPackageVersion>3.3.2</Tooling_MicrosoftCodeAnalysisAnalyzersPackageVersion>
<Tooling_MicrosoftCodeAnalysisNetAnalyzersPackageVersion>6.0.0-preview3.21158.1</Tooling_MicrosoftCodeAnalysisNetAnalyzersPackageVersion>
<Tooling_MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>$(RoslynPackageVersion)</Tooling_MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>
<Tooling_MicrosoftCodeAnalysisExternalAccessOmniSharpCSharpPackageVersion>$(RoslynPackageVersion)</Tooling_MicrosoftCodeAnalysisExternalAccessOmniSharpCSharpPackageVersion>
<Tooling_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>$(RoslynPackageVersion)</Tooling_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>
<Tooling_MicrosoftCodeAnalysisCSharpPackageVersion>$(RoslynPackageVersion)</Tooling_MicrosoftCodeAnalysisCSharpPackageVersion>
<Tooling_MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>$(RoslynPackageVersion)</Tooling_MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>

Просмотреть файл

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28410.60
# Visual Studio Version 17
VisualStudioVersion = 17.0.31415.485
MinimumVisualStudioVersion = 16.0.0.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}"
ProjectSection(SolutionItems) = preProject
@ -86,6 +86,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.Lang
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Remote.Razor.Test", "test\Microsoft.CodeAnalysis.Remote.Razor.Test\Microsoft.CodeAnalysis.Remote.Razor.Test.csproj", "{39233703-B752-43AC-AD86-E9D3E61B4AD9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Remote.Razor.CoreComponents", "src\Microsoft.CodeAnalysis.Remote.Razor.CoreComponents\Microsoft.CodeAnalysis.Remote.Razor.CoreComponents.csproj", "{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -390,6 +392,14 @@ Global
{39233703-B752-43AC-AD86-E9D3E61B4AD9}.Release|Any CPU.Build.0 = Release|Any CPU
{39233703-B752-43AC-AD86-E9D3E61B4AD9}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{39233703-B752-43AC-AD86-E9D3E61B4AD9}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.Release|Any CPU.Build.0 = Release|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -432,6 +442,7 @@ Global
{0FC409AF-B92B-42D0-9096-1F20360D2672} = {92463391-81BE-462B-AC3C-78C6C760741F}
{1C7BBF16-3507-4A23-91B4-9EEA03409C72} = {92463391-81BE-462B-AC3C-78C6C760741F}
{39233703-B752-43AC-AD86-E9D3E61B4AD9} = {92463391-81BE-462B-AC3C-78C6C760741F}
{17C4A6DF-3AA5-43FE-8A0E-53DF14340446} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0035341D-175A-4D05-95E6-F1C2785A1E26}

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Razor.Microbenchmarks.LanguageServer
private DocumentSnapshot UpdatedDocumentSnapshot { get; set; }
private ForegroundDispatcher ForegroundDispatcher { get; set; }
private ProjectSnapshotManagerDispatcher ProjectSnapshotManagerDispatcher { get; set; }
private string PagesDirectory { get; set; }
@ -76,7 +76,8 @@ namespace Microsoft.AspNetCore.Razor.Microbenchmarks.LanguageServer
private async Task UpdateDocumentAsync(int newVersion, DocumentSnapshot documentSnapshot)
{
await Task.Factory.StartNew(() => VersionCache.TrackDocumentVersion(documentSnapshot, newVersion), CancellationToken.None, TaskCreationOptions.None, ForegroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
await ProjectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => VersionCache.TrackDocumentVersion(documentSnapshot, newVersion), CancellationToken.None).ConfigureAwait(false);
}
[GlobalCleanup]
@ -101,7 +102,7 @@ namespace Microsoft.AspNetCore.Razor.Microbenchmarks.LanguageServer
var languageServer = RazorLanguageServer.GetInnerLanguageServerForTesting();
RazorSemanticTokenService = languageServer.GetService(typeof(RazorSemanticTokensInfoService)) as TestRazorSemanticTokensInfoService;
VersionCache = languageServer.GetService(typeof(DocumentVersionCache)) as DocumentVersionCache;
ForegroundDispatcher = languageServer.GetService(typeof(ForegroundDispatcher)) as ForegroundDispatcher;
ProjectSnapshotManagerDispatcher = languageServer.GetService(typeof(ProjectSnapshotManagerDispatcher)) as ProjectSnapshotManagerDispatcher;
}
private class TestRazorSemanticTokensInfoService : DefaultRazorSemanticTokensInfoService
@ -109,11 +110,11 @@ namespace Microsoft.AspNetCore.Razor.Microbenchmarks.LanguageServer
public TestRazorSemanticTokensInfoService(
ClientNotifierServiceBase languageServer,
RazorDocumentMappingService documentMappingService,
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
DocumentVersionCache documentVersionCache,
LoggerFactory loggerFactory) :
base(languageServer, documentMappingService, foregroundDispatcher, documentResolver, documentVersionCache, loggerFactory)
base(languageServer, documentMappingService, projectSnapshotManagerDispatcher, documentResolver, documentVersionCache, loggerFactory)
{
}

Просмотреть файл

@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Razor.Microbenchmarks
Array.Empty<ILanguageService>());
return new DefaultProjectSnapshotManager(
new TestForegroundDispatcher(),
new TestProjectSnapshotManagerDispatcher(),
new TestErrorReporter(),
Array.Empty<ProjectSnapshotChangeTrigger>(),
#pragma warning disable CA2000 // Dispose objects before losing scope
@ -91,13 +91,11 @@ namespace Microsoft.AspNetCore.Razor.Microbenchmarks
}
}
private class TestForegroundDispatcher : ForegroundDispatcher
private class TestProjectSnapshotManagerDispatcher : ProjectSnapshotManagerDispatcher
{
public override bool IsForegroundThread => true;
public override bool IsDispatcherThread => true;
public override TaskScheduler ForegroundScheduler => TaskScheduler.Default;
public override TaskScheduler BackgroundScheduler => TaskScheduler.Default;
public override TaskScheduler DispatcherScheduler => TaskScheduler.Default;
}
private class TestErrorReporter : ErrorReporter

Просмотреть файл

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
@ -13,36 +12,36 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
{
internal class BackgroundDocumentGenerator : ProjectSnapshotChangeTrigger
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly IEnumerable<DocumentProcessedListener> _documentProcessedListeners;
private readonly Dictionary<string, DocumentSnapshot> _work;
private ProjectSnapshotManagerBase _projectManager;
private Timer _timer;
public BackgroundDocumentGenerator(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
IEnumerable<DocumentProcessedListener> documentProcessedListeners)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentProcessedListeners == null)
if (documentProcessedListeners is null)
{
throw new ArgumentNullException(nameof(documentProcessedListeners));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentProcessedListeners = documentProcessedListeners;
_work = new Dictionary<string, DocumentSnapshot>(StringComparer.Ordinal);
}
// For testing only
protected BackgroundDocumentGenerator(
ForegroundDispatcher foregroundDispatcher)
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher)
{
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_work = new Dictionary<string, DocumentSnapshot>(StringComparer.Ordinal);
_documentProcessedListeners = Enumerable.Empty<DocumentProcessedListener>();
}
@ -136,7 +135,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
// Internal for testing
internal void Enqueue(DocumentSnapshot document)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
lock (_work)
{
@ -164,8 +163,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
{
try
{
_foregroundDispatcher.AssertBackgroundThread();
OnStartingBackgroundWork();
KeyValuePair<string, DocumentSnapshot>[] work;
@ -192,11 +189,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
OnCompletingBackgroundWork();
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => NotifyDocumentsProcessed(work),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
lock (_work)
{
@ -237,7 +232,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
private void ProjectSnapshotManager_Changed(object sender, ProjectChangeEventArgs args)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (args.Kind)
{
@ -317,11 +312,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
private void ReportError(Exception ex)
{
_ = Task.Factory.StartNew(
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectManager.ReportError(ex),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
}
}
}

Просмотреть файл

@ -9,14 +9,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
public const string ProjectConfigurationFile = "project.razor.json";
// Semantic "Legacy" endpoints refer to an old LSP spec version, needed for now until VS reacts.
public const string LegacyRazorSemanticTokensEndpoint = "textDocument/semanticTokens";
public const string LegacyRazorSemanticTokensEditEndpoint = "textDocument/semanticTokens/edits";
public const string LegacyRazorSemanticTokensRangeEndpoint = "textDocument/semanticTokens/range";
public const string RazorSemanticTokensLegendEndpoint = "_ms_/textDocument/semanticTokensLegend";
public const string RazorSemanticTokensLegendEndpoint = "_vs_/textDocument/semanticTokensLegend";
public const string RazorSemanticTokensEditEndpoint = "textDocument/semanticTokens/full/delta";
@ -36,8 +29,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
public const string RazorCodeActionRunnerCommand = "razor/runCodeAction";
public const string RazorCodeActionResolveEndpoint = "textDocument/codeActionResolve";
// RZLS Custom Message Targets
public const string RazorUpdateCSharpBufferEndpoint = "razor/updateCSharpBuffer";

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// 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;
@ -288,4 +288,4 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
SelfClosing,
}
}
}
}

Просмотреть файл

@ -5,7 +5,7 @@ using OmniSharp.Extensions.JsonRpc;
namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
{
[Parallel, Method("textDocument/_ms_onAutoInsert")]
[Parallel, Method("textDocument/_vs_onAutoInsert")]
internal interface IOnAutoInsertHandler : IJsonRpcRequestHandler<OnAutoInsertParams, OnAutoInsertResponse>, IRegistrationExtension
{
}

Просмотреть файл

@ -16,21 +16,21 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
{
internal class OnAutoInsertEndpoint : IOnAutoInsertHandler
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly AdhocWorkspaceFactory _workspaceFactory;
private readonly IReadOnlyList<RazorOnAutoInsertProvider> _onAutoInsertProviders;
private readonly Container<string> _onAutoInsertTriggerCharacters;
public OnAutoInsertEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
IEnumerable<RazorOnAutoInsertProvider> onAutoInsertProvider,
AdhocWorkspaceFactory workspaceFactory)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver is null)
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
throw new ArgumentNullException(nameof(workspaceFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_workspaceFactory = workspaceFactory;
_onAutoInsertProviders = onAutoInsertProvider.ToList();
@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
public RegistrationExtensionResult GetRegistration()
{
const string AssociatedServerCapability = "_ms_onAutoInsertProvider";
const string AssociatedServerCapability = "_vs_onAutoInsertProvider";
var registrationOptions = new OnAutoInsertRegistrationOptions()
{
@ -70,12 +70,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
public async Task<OnAutoInsertResponse> Handle(OnAutoInsertParams request, CancellationToken cancellationToken)
{
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.TextDocument.Uri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
if (document is null || cancellationToken.IsCancellationRequested)
{

Просмотреть файл

@ -9,13 +9,16 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
{
internal class OnAutoInsertParams : ITextDocumentIdentifierParams, IRequest<OnAutoInsertResponse>, IBaseRequest
{
[JsonProperty("_vs_textDocument")]
public TextDocumentIdentifier TextDocument { get; set; }
[JsonProperty("_vs_position")]
public Position Position { get; set; }
[JsonProperty("ch")]
[JsonProperty("_vs_ch")]
public string Character { get; set; }
[JsonProperty("_vs_options")]
public FormattingOptions Options { get; set; }
}
}

Просмотреть файл

@ -1,6 +1,7 @@
// 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 Newtonsoft.Json;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
@ -9,6 +10,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
{
public DocumentSelector DocumentSelector { get; set; }
[JsonProperty("_vs_triggerCharacters")]
public Container<string> TriggerCharacters { get; set; }
}
}

Просмотреть файл

@ -1,14 +1,17 @@
// 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 Newtonsoft.Json;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
namespace Microsoft.AspNetCore.Razor.LanguageServer.AutoInsert
{
internal class OnAutoInsertResponse
{
[JsonProperty("_vs_textEditFormat")]
public InsertTextFormat TextEditFormat { get; set; }
[JsonProperty("_vs_textEdit")]
public TextEdit TextEdit { get; set; }
}
}

Просмотреть файл

@ -23,13 +23,25 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
{
internal class AddUsingsCodeActionResolver : RazorCodeActionResolver
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
public AddUsingsCodeActionResolver(ForegroundDispatcher foregroundDispatcher, DocumentResolver documentResolver)
public AddUsingsCodeActionResolver(
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver is null)
{
throw new ArgumentNullException(nameof(documentResolver));
}
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
}
public override string Action => LanguageServerConstants.CodeActions.AddUsing;
@ -49,11 +61,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
var path = actionParams.Uri.GetAbsoluteOrUNCPath();
var documentSnapshot = await Task.Factory.StartNew(() =>
var documentSnapshot = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(path, out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (documentSnapshot is null)
{
return null;

Просмотреть файл

@ -19,18 +19,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
/// </summary>
internal class AddUsingsCSharpCodeActionResolver : CSharpCodeActionResolver
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly DocumentVersionCache _documentVersionCache;
public AddUsingsCSharpCodeActionResolver(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
ClientNotifierServiceBase languageServer,
DocumentVersionCache documentVersionCache)
: base(languageServer)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
_documentVersionCache = documentVersionCache ?? throw new ArgumentNullException(nameof(documentVersionCache));
}
@ -87,11 +87,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
return codeAction;
}
var documentSnapshot = await Task.Factory.StartNew(() =>
var documentSnapshot = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(csharpParams.RazorFileUri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (documentSnapshot is null)
{
return codeAction;
@ -109,11 +109,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
return null;
}
var documentVersion = await Task.Factory.StartNew(() =>
var documentVersion = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentVersionCache.TryGetDocumentVersion(documentSnapshot, out var version);
return version;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
var codeDocumentIdentifier = new VersionedTextDocumentIdentifier()
{

Просмотреть файл

@ -28,22 +28,22 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
TrimFinalNewlines = true
};
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly RazorFormattingService _razorFormattingService;
private readonly DocumentVersionCache _documentVersionCache;
public DefaultCSharpCodeActionResolver(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
ClientNotifierServiceBase languageServer,
RazorFormattingService razorFormattingService,
DocumentVersionCache documentVersionCache)
: base(languageServer)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver is null)
@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
throw new ArgumentNullException(nameof(documentVersionCache));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_razorFormattingService = razorFormattingService;
_documentVersionCache = documentVersionCache;
@ -99,11 +99,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
cancellationToken.ThrowIfCancellationRequested();
var documentSnapshot = await Task.Factory.StartNew(() =>
var documentSnapshot = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(csharpParams.RazorFileUri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (documentSnapshot is null)
{
@ -134,11 +134,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
cancellationToken.ThrowIfCancellationRequested();
var documentVersion = await Task.Factory.StartNew(() =>
var documentVersion = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentVersionCache.TryGetDocumentVersion(documentSnapshot, out var version);
return version;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
var codeDocumentIdentifier = new VersionedTextDocumentIdentifier()
{

Просмотреть файл

@ -19,20 +19,20 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
/// </summary>
internal class UnformattedRemappingCSharpCodeActionResolver : CSharpCodeActionResolver
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly DocumentVersionCache _documentVersionCache;
private readonly RazorDocumentMappingService _documentMappingService;
public UnformattedRemappingCSharpCodeActionResolver(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
ClientNotifierServiceBase languageServer,
DocumentVersionCache documentVersionCache,
RazorDocumentMappingService documentMappingService)
: base(languageServer)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
_documentVersionCache = documentVersionCache ?? throw new ArgumentNullException(nameof(documentVersionCache));
_documentMappingService = documentMappingService ?? throw new ArgumentNullException(nameof(documentMappingService));
@ -85,14 +85,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
return codeAction;
}
var (documentSnapshot, documentVersion) = await Task.Factory.StartNew(() =>
var (documentSnapshot, documentVersion) = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(csharpParams.RazorFileUri.ToUri().GetAbsoluteOrUNCPath(), out var documentSnapshot);
_documentVersionCache.TryGetDocumentVersion(documentSnapshot, out var version);
return (documentSnapshot, version);
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (documentSnapshot is null)
{

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
private readonly RazorDocumentMappingService _documentMappingService;
private readonly IEnumerable<RazorCodeActionProvider> _razorCodeActionProviders;
private readonly IEnumerable<CSharpCodeActionProvider> _csharpCodeActionProviders;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly LanguageServerFeatureOptions _languageServerFeatureOptions;
private readonly ClientNotifierServiceBase _languageServer;
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
RazorDocumentMappingService documentMappingService,
IEnumerable<RazorCodeActionProvider> razorCodeActionProviders,
IEnumerable<CSharpCodeActionProvider> csharpCodeActionProviders,
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
ClientNotifierServiceBase languageServer,
LanguageServerFeatureOptions languageServerFeatureOptions)
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
_documentMappingService = documentMappingService ?? throw new ArgumentNullException(nameof(documentMappingService));
_razorCodeActionProviders = razorCodeActionProviders ?? throw new ArgumentNullException(nameof(razorCodeActionProviders));
_csharpCodeActionProviders = csharpCodeActionProviders ?? throw new ArgumentNullException(nameof(csharpCodeActionProviders));
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
_languageServer = languageServer ?? throw new ArgumentNullException(nameof(languageServer));
_languageServerFeatureOptions = languageServerFeatureOptions ?? throw new ArgumentNullException(nameof(languageServerFeatureOptions));
@ -65,7 +65,8 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
CodeActionKind.RefactorExtract,
CodeActionKind.QuickFix,
CodeActionKind.Refactor
}
},
ResolveProvider = true,
};
}
@ -73,8 +74,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
{
_capability = capability;
var extendableClientCapabilities = _languageServer.ClientSettings?.Capabilities as PlatformAgnosticClientCapabilities;
_supportsCodeActionResolve = extendableClientCapabilities?.SupportsCodeActionResolve ?? false;
_supportsCodeActionResolve = _capability.ResolveSupport != null;
}
public async Task<CommandOrCodeActionContainer> Handle(RazorCodeActionParams request, CancellationToken cancellationToken)
@ -121,11 +121,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
// internal for testing
internal async Task<RazorCodeActionContext> GenerateRazorCodeActionContextAsync(RazorCodeActionParams request, CancellationToken cancellationToken)
{
var documentSnapshot = await Task.Factory.StartNew(() =>
var documentSnapshot = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.TextDocument.Uri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (documentSnapshot is null)
{

Просмотреть файл

@ -16,8 +16,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
{
internal class CodeActionResolutionEndpoint : IRazorCodeActionResolveHandler
{
private const string CodeActionsResolveProviderCapability = "codeActionsResolveProvider";
private readonly IReadOnlyDictionary<string, RazorCodeActionResolver> _razorCodeActionResolvers;
private readonly IReadOnlyDictionary<string, CSharpCodeActionResolver> _csharpCodeActionResolvers;
private readonly ILogger _logger;
@ -48,9 +46,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
_csharpCodeActionResolvers = CreateResolverMap(csharpCodeActionResolvers);
}
// Register VS LSP code action resolution server capability
public RegistrationExtensionResult GetRegistration() => new RegistrationExtensionResult(CodeActionsResolveProviderCapability, true);
public async Task<CodeAction> Handle(CodeAction request, CancellationToken cancellationToken)
{
if (request is null)

Просмотреть файл

@ -1,16 +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 Microsoft.AspNetCore.Razor.LanguageServer.Common;
using OmniSharp.Extensions.JsonRpc;
using OmniSharp.Extensions.LanguageServer.Protocol;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
{
[Parallel, Method(LanguageServerConstants.RazorCodeActionResolveEndpoint)]
[Parallel, Method(TextDocumentNames.CodeActionResolve, Direction.ClientToServer)]
internal interface IRazorCodeActionResolveHandler :
IJsonRpcRequestHandler<CodeAction, CodeAction>,
IRegistrationExtension
IJsonRpcRequestHandler<CodeAction, CodeAction>
{
}
}

Просмотреть файл

@ -1,6 +1,7 @@
// 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 Newtonsoft.Json;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
@ -9,6 +10,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions.Models
internal class ExtendedCodeActionContext : CodeActionContext
{
[Optional]
[JsonProperty("_vs_selectionRange")]
public Range SelectionRange { get; set; }
}
}

Просмотреть файл

@ -20,14 +20,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
{
internal class CreateComponentCodeActionResolver : RazorCodeActionResolver
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
public CreateComponentCodeActionResolver(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
}
@ -48,11 +48,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
var path = actionParams.Uri.GetAbsoluteOrUNCPath();
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(path, out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (document is null)
{
return null;

Просмотреть файл

@ -26,18 +26,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
{
internal class ExtractToCodeBehindCodeActionResolver : RazorCodeActionResolver
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly FilePathNormalizer _filePathNormalizer;
private static readonly Range s_startOfDocumentRange = new Range(new Position(0, 0), new Position(0, 0));
public ExtractToCodeBehindCodeActionResolver(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
FilePathNormalizer filePathNormalizer)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
_filePathNormalizer = filePathNormalizer ?? throw new ArgumentNullException(nameof(filePathNormalizer));
}
@ -59,11 +59,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions
var path = _filePathNormalizer.Normalize(actionParams.Uri.GetAbsoluteOrUNCPath());
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(path, out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (document is null)
{
return null;

Просмотреть файл

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
{
public static readonly PlatformExtensionConverter<CompletionContext, OmniSharpVSCompletionContext> JsonConverter = new PlatformExtensionConverter<CompletionContext, OmniSharpVSCompletionContext>();
[JsonProperty("_ms_invokeKind")]
[JsonProperty("_vs_invokeKind")]
public OmniSharpVSCompletionInvokeKind InvokeKind { get; set; }
}
}

Просмотреть файл

@ -29,13 +29,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
if (vsCompletionList.CommitCharacters != null)
{
writer.WritePropertyName("_vsext_commitCharacters");
writer.WritePropertyName("_vs_commitCharacters");
serializer.Serialize(writer, vsCompletionList.CommitCharacters);
}
if (vsCompletionList.Data != null)
{
writer.WritePropertyName("_vsext_data");
writer.WritePropertyName("_vs_data");
serializer.Serialize(writer, vsCompletionList.Data);
}

Просмотреть файл

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
{
public static readonly PlatformExtensionConverter<CompletionCapability, PlatformAgnosticCompletionCapability> JsonConverter = new PlatformExtensionConverter<CompletionCapability, PlatformAgnosticCompletionCapability>();
[JsonProperty("_ms_completionList")]
[JsonProperty("_vs_completionList")]
public VSCompletionListCapability VSCompletionList { get; set; }
}
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
{
private PlatformAgnosticCompletionCapability _capability;
private readonly ILogger _logger;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly RazorCompletionFactsService _completionFactsService;
private readonly LSPTagHelperTooltipFactory _lspTagHelperTooltipFactory;
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
private IReadOnlyList<ExtendedCompletionItemKinds> _supportedItemKinds;
public RazorCompletionEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
RazorCompletionFactsService completionFactsService,
LSPTagHelperTooltipFactory lspTagHelperTooltipFactory,
@ -49,9 +49,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
ClientNotifierServiceBase languageServer,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver == null)
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_completionFactsService = completionFactsService;
_lspTagHelperTooltipFactory = lspTagHelperTooltipFactory;
@ -102,14 +102,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
public async Task<CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken)
{
_foregroundDispatcher.AssertBackgroundThread();
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.TextDocument.Uri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, CancellationToken.None);
if (document is null || cancellationToken.IsCancellationRequested)
{

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Razor.LanguageServer.Tooltip;
using Newtonsoft.Json;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
@ -11,6 +12,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
/// </summary>
internal class VSCompletionItem : CompletionItem
{
[JsonProperty("_vs_description")]
public VSClassifiedTextElement Description { get; set; }
}
}

Просмотреть файл

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
@ -19,11 +20,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
/// <summary>
/// Gets or sets the default <see cref="CompletionItem.CommitCharacters"/> used for completion items.
/// </summary>
[JsonProperty("_vs_commitCharacters")]
public Container<string> CommitCharacters { get; set; }
/// <summary>
/// Gets or sets the default <see cref="CompletionItem.Data"/> used for completion items.
/// </summary>
[JsonProperty("_vs_data")]
public object Data { get; set; }
public static VSCompletionList Convert(CompletionList completionList, VSCompletionListCapability vsCompletionListCapability)

Просмотреть файл

@ -1,6 +1,8 @@
// 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 Newtonsoft.Json;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
{
internal class VSCompletionListCapability
@ -9,12 +11,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion
/// Gets or sets a value indicating whether completion lists can have VSCommitCharacters. These commit characters get propagated
/// onto underlying valid completion items unless they have their own commit characters.
/// </summary>
[JsonProperty("_vs_commitCharacters")]
public bool CommitCharacters { get; set; }
/// <summary>
/// Gets or sets a value indicating whether completion lists can have Data bags. These data bags get propagated
/// onto underlying completion items unless they have their own data bags.
/// </summary>
[JsonProperty("_vs_data")]
public bool Data { get; set; }
}
}

Просмотреть файл

@ -14,18 +14,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
// Internal for testing
internal readonly Dictionary<string, List<DocumentEntry>> DocumentLookup;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private ProjectSnapshotManagerBase _projectSnapshotManager;
public DefaultDocumentVersionCache(ForegroundDispatcher foregroundDispatcher)
public DefaultDocumentVersionCache(ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
_foregroundDispatcher = foregroundDispatcher;
DocumentLookup = new Dictionary<string, List<DocumentEntry>>(FilePathComparer.Instance);
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
}
public override void TrackDocumentVersion(DocumentSnapshot documentSnapshot, int version)
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(documentSnapshot));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (!DocumentLookup.TryGetValue(documentSnapshot.FilePath, out var documentEntries))
{
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(documentSnapshot));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (!DocumentLookup.TryGetValue(documentSnapshot.FilePath, out var documentEntries))
{
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private void ProjectSnapshotManager_Changed(object sender, ProjectChangeEventArgs args)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (args.Kind)
{

Просмотреть файл

@ -4,7 +4,6 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
@ -13,19 +12,19 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
internal class DefaultGeneratedDocumentContainerStore : GeneratedDocumentContainerStore
{
private readonly ConcurrentDictionary<string, ReferenceOutputCapturingContainer> _store;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentVersionCache _documentVersionCache;
private readonly GeneratedDocumentPublisher _generatedDocumentPublisher;
private ProjectSnapshotManagerBase _projectSnapshotManager;
public DefaultGeneratedDocumentContainerStore(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentVersionCache documentVersionCache,
GeneratedDocumentPublisher generatedDocumentPublisher)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentVersionCache == null)
@ -38,7 +37,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(generatedDocumentPublisher));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentVersionCache = documentVersionCache;
_generatedDocumentPublisher = generatedDocumentPublisher;
_store = new ConcurrentDictionary<string, ReferenceOutputCapturingContainer>(FilePathComparer.Instance);
@ -67,7 +66,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
// Internal for testing
internal void ProjectSnapshotManager_Changed(object sender, ProjectChangeEventArgs args)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (args.Kind)
{
@ -95,7 +94,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
var latestDocument = generatedDocumentContainer.LatestDocument;
_ = Task.Factory.StartNew(() =>
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
if (!_projectSnapshotManager.IsDocumentOpen(filePath))
{
@ -111,7 +110,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
var hostDocumentVersion = nullableHostDocumentVersion.Value;
_generatedDocumentPublisher.PublishCSharp(filePath, args.NewText, hostDocumentVersion);
}, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, CancellationToken.None);
};
documentContainer.GeneratedHtmlChanged += (sender, args) =>
@ -120,7 +119,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
var latestDocument = generatedDocumentContainer.LatestDocument;
_ = Task.Factory.StartNew(() =>
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
if (!_projectSnapshotManager.IsDocumentOpen(filePath))
{
@ -136,7 +135,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
var hostDocumentVersion = nullableHostDocumentVersion.Value;
_generatedDocumentPublisher.PublishHtml(filePath, args.NewText, hostDocumentVersion);
}, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, CancellationToken.None);
};
return documentContainer;

Просмотреть файл

@ -20,17 +20,17 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private readonly Dictionary<string, PublishData> _publishedHtmlData;
private readonly IClientLanguageServer _server;
private readonly ILogger _logger;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private ProjectSnapshotManagerBase _projectSnapshotManager;
public DefaultGeneratedDocumentPublisher(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
IClientLanguageServer server,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (server is null)
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_server = server;
_logger = loggerFactory.CreateLogger<DefaultGeneratedDocumentPublisher>();
_publishedCSharpData = new Dictionary<string, PublishData>(FilePathComparer.Instance);
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(sourceText));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (!_publishedCSharpData.TryGetValue(filePath, out var previouslyPublishedData))
{
@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(sourceText));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (!_publishedHtmlData.TryGetValue(filePath, out var previouslyPublishedData))
{
@ -167,7 +167,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private void ProjectSnapshotManager_Changed(object sender, ProjectChangeEventArgs args)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (args.Kind)
{
@ -178,12 +178,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
if (_publishedCSharpData.ContainsKey(args.DocumentFilePath))
{
var removed = _publishedCSharpData.Remove(args.DocumentFilePath);
Debug.Assert(removed, "Published data should be protected by the foreground thread and should never fail to remove.");
Debug.Assert(removed, "Published data should be protected by the project snapshot manager's thread and should never fail to remove.");
}
if (_publishedHtmlData.ContainsKey(args.DocumentFilePath))
{
var removed = _publishedHtmlData.Remove(args.DocumentFilePath);
Debug.Assert(removed, "Published data should be protected by the foreground thread and should never fail to remove.");
Debug.Assert(removed, "Published data should be protected by the project snapshot manager's thread and should never fail to remove.");
}
}
break;

Просмотреть файл

@ -4,7 +4,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
using Microsoft.CodeAnalysis.Text;
@ -12,24 +11,15 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class DefaultHostDocumentFactory : HostDocumentFactory
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly GeneratedDocumentContainerStore _generatedDocumentContainerStore;
public DefaultHostDocumentFactory(
ForegroundDispatcher foregroundDispatcher,
GeneratedDocumentContainerStore generatedDocumentContainerStore)
public DefaultHostDocumentFactory(GeneratedDocumentContainerStore generatedDocumentContainerStore)
{
if (foregroundDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
}
if (generatedDocumentContainerStore == null)
if (generatedDocumentContainerStore is null)
{
throw new ArgumentNullException(nameof(generatedDocumentContainerStore));
}
_foregroundDispatcher = foregroundDispatcher;
_generatedDocumentContainerStore = generatedDocumentContainerStore;
}
@ -38,12 +28,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
public override HostDocument Create(string filePath, string targetFilePath, string fileKind)
{
if (filePath == null)
if (filePath is null)
{
throw new ArgumentNullException(nameof(filePath));
}
if (targetFilePath == null)
if (targetFilePath is null)
{
throw new ArgumentNullException(nameof(targetFilePath));
}
@ -64,7 +54,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
() => sharedContainer.SetOutputAndCaptureReferenceAsync(latestDocument),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.BackgroundScheduler);
TaskScheduler.Default);
}
}
}

Просмотреть файл

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class DefaultProjectSnapshotManagerAccessor : ProjectSnapshotManagerAccessor, IDisposable
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly IEnumerable<ProjectSnapshotChangeTrigger> _changeTriggers;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly IOptionsMonitor<RazorLSPOptions> _optionsMonitor;
@ -21,15 +21,15 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private bool _disposed;
public DefaultProjectSnapshotManagerAccessor(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
IEnumerable<ProjectSnapshotChangeTrigger> changeTriggers,
FilePathNormalizer filePathNormalizer,
IOptionsMonitor<RazorLSPOptions> optionsMonitor,
AdhocWorkspaceFactory workspaceFactory)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (changeTriggers == null)
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(workspaceFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_changeTriggers = changeTriggers;
_filePathNormalizer = filePathNormalizer;
_optionsMonitor = optionsMonitor;
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
new RemoteProjectSnapshotProjectEngineFactory(_filePathNormalizer, _optionsMonitor)
});
_instance = new DefaultProjectSnapshotManager(
_foregroundDispatcher,
_projectSnapshotManagerDispatcher,
new DefaultErrorReporter(),
_changeTriggers,
workspace);

Просмотреть файл

@ -15,14 +15,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class DefaultRazorComponentSearchEngine : RazorComponentSearchEngine
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly ProjectSnapshotManager _projectSnapshotManager;
public DefaultRazorComponentSearchEngine(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
ProjectSnapshotManagerAccessor projectSnapshotManagerAccessor)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_projectSnapshotManager = projectSnapshotManagerAccessor?.Instance ?? throw new ArgumentNullException(nameof(projectSnapshotManagerAccessor));
}
@ -45,11 +45,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
DefaultRazorTagHelperBinderPhase.ComponentDirectiveVisitor.TrySplitNamespaceAndType(tagHelper.Name, out var @namespaceName, out var typeName);
var lookupSymbolName = RemoveGenericContent(typeName);
var projects = await Task.Factory.StartNew(
var projects = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectSnapshotManager.Projects.ToArray(),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
CancellationToken.None).ConfigureAwait(false);
foreach (var project in projects)
{

Просмотреть файл

@ -21,16 +21,16 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Definition
{
internal class RazorDefinitionEndpoint : IDefinitionHandler
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly RazorComponentSearchEngine _componentSearchEngine;
public RazorDefinitionEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
RazorComponentSearchEngine componentSearchEngine)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
_componentSearchEngine = componentSearchEngine ?? throw new ArgumentNullException(nameof(componentSearchEngine));
}
@ -50,12 +50,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Definition
throw new ArgumentNullException(nameof(request));
}
var documentSnapshot = await Task.Factory.StartNew(() =>
var documentSnapshot = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
var path = request.TextDocument.Uri.GetAbsoluteOrUNCPath();
_documentResolver.TryResolveDocument(path, out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (documentSnapshot is null)
{

Просмотреть файл

@ -20,46 +20,46 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
/// <summary>
/// Gets or sets the project and context (e.g. Win32, MacOS, etc.) in which the diagnostic was generated.
/// </summary>
[JsonProperty("_ms_projects")]
public OmniSharpVSProjectAndContext[]? Projects { get; set; }
[JsonProperty("_vs_projects")]
public OmniSharpVSDiagnosticProjectInformation[]? Projects { get; set; }
/// <summary>
/// Gets or sets an expanded description of the diagnostic.
/// </summary>
[JsonProperty("_ms_expandedMessage")]
[JsonProperty("_vs_expandedMessage")]
public string? ExpandedMessage { get; set; }
/// <summary>
/// Gets or sets a message shown when the user hovers over an error. If null, then message
/// is used (use <see cref="OmniSharpVSDiagnosticTags.SuppressEditorToolTip"/> to prevent a tool tip from being shown).
/// </summary>
[JsonProperty("_ms_toolTip")]
[JsonProperty("_vs_toolTip")]
public string? ToolTip { get; set; }
/// <summary>
/// Gets or sets some non-human readable identifier so that two diagnostics that are
/// equivalent (e.g.a syntax error in both a build for Win32 and MacOs) can be consolidated.
/// </summary>
[JsonProperty("_ms_identifier")]
[JsonProperty("_vs_identifier")]
public string? Identifier { get; set; }
/// <summary>
/// Gets or sets a string describing the diagnostic types (e.g. Security, Performance, Style, ...).
/// </summary>
[JsonProperty("_ms_diagnosticType")]
[JsonProperty("_vs_diagnosticType")]
public string? DiagnosticType { get; set; }
/// <summary>
/// Gets or sets a rank associated with this diagnostic, used for the default sort.
/// Default == 300 will be used if no rank is specified.
/// </summary>
[JsonProperty("_ms_diagnosticRank")]
[JsonProperty("_vs_diagnosticRank")]
public OmniSharpVSDiagnosticRank? DiagnosticRank { get; set; }
/// <summary>
/// Gets or sets an ID used to associate this diagnostic with a corresponding line in the output window.
/// </summary>
[JsonProperty("_ms_outputId")]
[JsonProperty("_vs_outputId")]
public int? OutputId { get; set; }
}
}

Просмотреть файл

@ -3,24 +3,29 @@
#nullable enable
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
{
internal class OmniSharpVSProjectAndContext
internal class OmniSharpVSDiagnosticProjectInformation
{
/// <summary>
/// Gets or sets a human-readable identifier for the project in which the diagnostic was generated.
/// </summary>
[JsonProperty("_vs_projectName")]
public string? ProjectName { get; set; }
/// <summary>
/// Gets or sets a human-readable identifier for the build context (e.g. Win32 or MacOS)
/// in which the diagnostic was generated.
/// </summary>
[JsonProperty("_vs_context")]
public string? Context { get; set; }
/// <summary>
/// Gets or sets the unique identifier for the project in which the diagnostic was generated.
/// </summary>
[JsonProperty("_vs_projectIdentifier")]
public string? ProjectIdentifier { get; set; }
}
}

Просмотреть файл

@ -30,22 +30,22 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
"IDE0005_gen", // Using directive is unnecessary
};
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly DocumentVersionCache _documentVersionCache;
private readonly RazorDocumentMappingService _documentMappingService;
private readonly ILogger _logger;
public RazorDiagnosticsEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
DocumentVersionCache documentVersionCache,
RazorDocumentMappingService documentMappingService,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver == null)
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_documentVersionCache = documentVersionCache;
_documentMappingService = documentMappingService;
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
int? documentVersion = null;
DocumentSnapshot documentSnapshot = null;
await Task.Factory.StartNew(() =>
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.RazorDocumentUri.GetAbsoluteOrUNCPath(), out documentSnapshot);
@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics
{
documentVersion = null;
}
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (documentSnapshot is null)
{

Просмотреть файл

@ -36,6 +36,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
TextDocumentSync = inner.TextDocumentSync;
CodeLensProvider = inner.CodeLensProvider;
Workspace = inner.Workspace;
#pragma warning disable CS0618 // Type or member is obsolete
SemanticTokensProvider = inner.SemanticTokensProvider;
#pragma warning restore CS0618 // Type or member is obsolete
RazorLanguageServerCapability.AddTo(this);

Просмотреть файл

@ -22,22 +22,22 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting
{
internal class RazorFormattingEndpoint : IDocumentFormattingHandler, IDocumentRangeFormattingHandler
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly RazorFormattingService _razorFormattingService;
private readonly IOptionsMonitor<RazorLSPOptions> _optionsMonitor;
private readonly ILogger _logger;
public RazorFormattingEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
RazorFormattingService razorFormattingService,
IOptionsMonitor<RazorLSPOptions> optionsMonitor,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver is null)
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_razorFormattingService = razorFormattingService;
_optionsMonitor = optionsMonitor;
@ -90,12 +90,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting
return null;
}
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.TextDocument.Uri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
if (document is null || cancellationToken.IsCancellationRequested)
{
@ -124,12 +124,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting
return null;
}
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.TextDocument.Uri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
if (document is null || cancellationToken.IsCancellationRequested)
{

Просмотреть файл

@ -21,21 +21,21 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Hover
{
private HoverCapability _capability;
private readonly ILogger _logger;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly RazorHoverInfoService _hoverInfoService;
private readonly ClientNotifierServiceBase _languageServer;
public RazorHoverEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
RazorHoverInfoService hoverInfoService,
ClientNotifierServiceBase languageServer,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver is null)
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Hover
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_hoverInfoService = hoverInfoService;
_languageServer = languageServer;
@ -72,12 +72,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Hover
throw new ArgumentNullException(nameof(request));
}
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.TextDocument.Uri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
if (document is null)
{

Просмотреть файл

@ -3,12 +3,14 @@
#nullable enable
using Newtonsoft.Json;
using HoverModel = OmniSharp.Extensions.LanguageServer.Protocol.Models.Hover;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Hover
{
internal class VSHover : HoverModel
{
[JsonProperty("_vs_rawContent")]
public object? RawContent { get; set; }
}
}

Просмотреть файл

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class MonitorProjectConfigurationFilePathEndpoint : IMonitorProjectConfigurationFilePathHandler, IDisposable
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly WorkspaceDirectoryPathResolver _workspaceDirectoryPathResolver;
private readonly IEnumerable<IProjectConfigurationFileChangeListener> _listeners;
@ -25,14 +25,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private bool _disposed;
public MonitorProjectConfigurationFilePathEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
FilePathNormalizer filePathNormalizer,
WorkspaceDirectoryPathResolver workspaceDirectoryPathResolver,
IEnumerable<IProjectConfigurationFileChangeListener> listeners)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (filePathNormalizer is null)
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(listeners));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_filePathNormalizer = filePathNormalizer;
_workspaceDirectoryPathResolver = workspaceDirectoryPathResolver;
_listeners = listeners;
@ -191,6 +191,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
}
// Protected virtual for testing
protected virtual IFileChangeDetector CreateFileChangeDetector() => new ProjectConfigurationFileChangeDetector(_foregroundDispatcher, _filePathNormalizer, _listeners);
protected virtual IFileChangeDetector CreateFileChangeDetector() => new ProjectConfigurationFileChangeDetector(_projectSnapshotManagerDispatcher, _filePathNormalizer, _listeners);
}
}

Просмотреть файл

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
using Microsoft.Extensions.Internal;
@ -14,35 +13,35 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class OpenDocumentGenerator : ProjectSnapshotChangeTrigger
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly IReadOnlyList<DocumentProcessedListener> _documentProcessedListeners;
private readonly Dictionary<string, DocumentSnapshot> _work;
private ProjectSnapshotManagerBase _projectManager;
private Timer _timer;
public OpenDocumentGenerator(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
IEnumerable<DocumentProcessedListener> documentProcessedListeners)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentProcessedListeners == null)
if (documentProcessedListeners is null)
{
throw new ArgumentNullException(nameof(documentProcessedListeners));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentProcessedListeners = documentProcessedListeners.ToArray();
_work = new Dictionary<string, DocumentSnapshot>(StringComparer.Ordinal);
}
// For testing only
protected OpenDocumentGenerator(ForegroundDispatcher foregroundDispatcher)
protected OpenDocumentGenerator(ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher)
{
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_work = new Dictionary<string, DocumentSnapshot>(StringComparer.Ordinal);
_documentProcessedListeners = Array.Empty<DocumentProcessedListener>();
}
@ -136,7 +135,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
// Internal for testing
internal void Enqueue(DocumentSnapshot document)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (!_projectManager.IsDocumentOpen(document.FilePath))
{
@ -170,8 +169,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
try
{
_foregroundDispatcher.AssertBackgroundThread();
OnStartingBackgroundWork();
KeyValuePair<string, DocumentSnapshot>[] work;
@ -200,11 +197,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
if (_documentProcessedListeners.Count != 0)
{
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => NotifyDocumentsProcessed(work),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
CancellationToken.None).ConfigureAwait(false);
}
lock (_work)
@ -246,7 +241,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private void ProjectSnapshotManager_Changed(object sender, ProjectChangeEventArgs args)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (args.Kind)
{
@ -308,11 +303,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private void ReportError(Exception ex)
{
_ = Task.Factory.StartNew(
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectManager.ReportError(ex),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
}
}
}

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Razor.LanguageServer.Serialization;
using Newtonsoft.Json;
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
namespace Microsoft.AspNetCore.Razor.LanguageServer
@ -13,8 +14,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
public static readonly PlatformExtensionConverter<ClientCapabilities, PlatformAgnosticClientCapabilities> JsonConverter = new PlatformExtensionConverter<ClientCapabilities, PlatformAgnosticClientCapabilities>();
public bool SupportsCodeActionResolve { get; set; } = false;
[JsonProperty("_vs_supportsVisualStudioExtensions")]
public bool SupportsVisualStudioExtensions { get; set; } = false;
}
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class ProjectConfigurationFileChangeDetector : IFileChangeDetector
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly IEnumerable<IProjectConfigurationFileChangeListener> _listeners;
private readonly ILogger _logger;
@ -28,14 +28,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
};
public ProjectConfigurationFileChangeDetector(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
FilePathNormalizer filePathNormalizer,
IEnumerable<IProjectConfigurationFileChangeListener> listeners,
ILoggerFactory loggerFactory = null)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (filePathNormalizer is null)
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(listeners));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_filePathNormalizer = filePathNormalizer;
_listeners = listeners;
_logger = loggerFactory?.CreateLogger<ProjectConfigurationFileChangeDetector>();
@ -66,13 +66,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
workspaceDirectory = _filePathNormalizer.Normalize(workspaceDirectory);
var existingConfigurationFiles = GetExistingConfigurationFiles(workspaceDirectory);
await Task.Factory.StartNew(() =>
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
foreach (var configurationFilePath in existingConfigurationFiles)
{
FileSystemWatcher_ProjectConfigurationFileEvent(configurationFilePath, RazorFileChangeKind.Added);
}
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
// This is an entry point for testing
OnInitializationFinished();
@ -134,9 +134,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private void FileSystemWatcher_ProjectConfigurationFileEvent_Background(string physicalFilePath, RazorFileChangeKind kind)
{
_ = Task.Factory.StartNew(
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => FileSystemWatcher_ProjectConfigurationFileEvent(physicalFilePath, kind),
CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
}
private void FileSystemWatcher_ProjectConfigurationFileEvent(string physicalFilePath, RazorFileChangeKind kind)

Просмотреть файл

@ -14,20 +14,20 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class ProjectConfigurationStateSynchronizer : IProjectConfigurationFileChangeListener
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly RazorProjectService _projectService;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly Dictionary<string, string> _configurationToProjectMap;
internal readonly Dictionary<string, DelayedProjectInfo> ProjectInfoMap;
public ProjectConfigurationStateSynchronizer(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
RazorProjectService projectService,
FilePathNormalizer filePathNormalizer)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (projectService is null)
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(filePathNormalizer));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_projectService = projectService;
_filePathNormalizer = filePathNormalizer;
_configurationToProjectMap = new Dictionary<string, string>(FilePathComparer.Instance);
@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(args));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (args.Kind)
{

Просмотреть файл

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
private const string ProjectFileExtension = ".csproj";
private const string ProjectFileExtensionPattern = "*" + ProjectFileExtension;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly IEnumerable<IProjectFileChangeListener> _listeners;
private FileSystemWatcher _watcher;
@ -28,13 +28,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
};
public ProjectFileChangeDetector(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
FilePathNormalizer filePathNormalizer,
IEnumerable<IProjectFileChangeListener> listeners)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (filePathNormalizer is null)
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(listeners));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_filePathNormalizer = filePathNormalizer;
_listeners = listeners;
}
@ -64,13 +64,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
workspaceDirectory = _filePathNormalizer.Normalize(workspaceDirectory);
var existingProjectFiles = GetExistingProjectFiles(workspaceDirectory);
await Task.Factory.StartNew(() =>
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
foreach (var projectFilePath in existingProjectFiles)
{
FileSystemWatcher_ProjectFileEvent(projectFilePath, RazorFileChangeKind.Added);
}
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
// This is an entry point for testing
OnInitializationFinished();
@ -134,9 +134,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private void FileSystemWatcher_ProjectFileEvent_Background(string physicalFilePath, RazorFileChangeKind kind)
{
_ = Task.Factory.StartNew(
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => FileSystemWatcher_ProjectFileEvent(physicalFilePath, kind),
CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
}
private void FileSystemWatcher_ProjectFileEvent(string physicalFilePath, RazorFileChangeKind kind)

Просмотреть файл

@ -10,16 +10,16 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class ProjectFileSynchronizer : IProjectFileChangeListener
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly RazorProjectService _projectService;
public ProjectFileSynchronizer(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
RazorProjectService projectService)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (projectService is null)
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(projectService));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_projectService = projectService;
}
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(filePath));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (kind)
{

Просмотреть файл

@ -10,18 +10,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
{
internal class DefaultDocumentResolver : DocumentResolver
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly ProjectResolver _projectResolver;
private readonly FilePathNormalizer _filePathNormalizer;
public DefaultDocumentResolver(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
ProjectResolver projectResolver,
FilePathNormalizer filePathNormalizer)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (projectResolver == null)
@ -34,14 +34,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
throw new ArgumentNullException(nameof(filePathNormalizer));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_projectResolver = projectResolver;
_filePathNormalizer = filePathNormalizer;
}
public override bool TryResolveDocument(string documentFilePath, out DocumentSnapshot document)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var normalizedPath = _filePathNormalizer.Normalize(documentFilePath);
if (!_projectResolver.TryResolveProject(normalizedPath, out var project))

Просмотреть файл

@ -14,18 +14,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
// Internal for testing
protected internal readonly HostProject MiscellaneousHostProject;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly ProjectSnapshotManagerAccessor _projectSnapshotManagerAccessor;
public DefaultProjectResolver(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
FilePathNormalizer filePathNormalizer,
ProjectSnapshotManagerAccessor projectSnapshotManagerAccessor)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (filePathNormalizer == null)
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
throw new ArgumentNullException(nameof(projectSnapshotManagerAccessor));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_filePathNormalizer = filePathNormalizer;
_projectSnapshotManagerAccessor = projectSnapshotManagerAccessor;
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
throw new ArgumentNullException(nameof(documentFilePath));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var normalizedDocumentPath = _filePathNormalizer.Normalize(documentFilePath);
var projects = _projectSnapshotManagerAccessor.Instance.Projects;
@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override ProjectSnapshot GetMiscellaneousProject()
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var miscellaneousProject = _projectSnapshotManagerAccessor.Instance.GetLoadedProject(MiscellaneousHostProject.FilePath);
if (miscellaneousProject == null)

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
internal class DefaultRazorProjectService : RazorProjectService
{
private readonly ProjectSnapshotManagerAccessor _projectSnapshotManagerAccessor;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly HostDocumentFactory _hostDocumentFactory;
private readonly RemoteTextLoaderFactory _remoteTextLoaderFactory;
private readonly ProjectResolver _projectResolver;
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
private readonly ILogger _logger;
public DefaultRazorProjectService(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
HostDocumentFactory hostDocumentFactory,
RemoteTextLoaderFactory remoteTextLoaderFactory,
DocumentResolver documentResolver,
@ -41,9 +41,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
ProjectSnapshotManagerAccessor projectSnapshotManagerAccessor,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (hostDocumentFactory == null)
@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_hostDocumentFactory = hostDocumentFactory;
_remoteTextLoaderFactory = remoteTextLoaderFactory;
_documentResolver = documentResolver;
@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override void AddDocument(string filePath)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var textDocumentPath = _filePathNormalizer.Normalize(filePath);
if (_documentResolver.TryResolveDocument(textDocumentPath, out var _))
@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override void OpenDocument(string filePath, SourceText sourceText, int version)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var textDocumentPath = _filePathNormalizer.Normalize(filePath);
if (!_documentResolver.TryResolveDocument(textDocumentPath, out _))
@ -166,7 +166,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override void CloseDocument(string filePath)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var textDocumentPath = _filePathNormalizer.Normalize(filePath);
if (!_projectResolver.TryResolveProject(textDocumentPath, out var projectSnapshot))
@ -182,7 +182,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override void RemoveDocument(string filePath)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var textDocumentPath = _filePathNormalizer.Normalize(filePath);
if (!_projectResolver.TryResolveProject(textDocumentPath, out var projectSnapshot))
@ -204,7 +204,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override void UpdateDocument(string filePath, SourceText sourceText, int version)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var textDocumentPath = _filePathNormalizer.Normalize(filePath);
if (!_projectResolver.TryResolveProject(textDocumentPath, out var projectSnapshot))
@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override void AddProject(string filePath)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var normalizedPath = _filePathNormalizer.Normalize(filePath);
@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
public override void RemoveProject(string filePath)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var normalizedPath = _filePathNormalizer.Normalize(filePath);
var project = (DefaultProjectSnapshot)_projectSnapshotManagerAccessor.Instance.GetLoadedProject(normalizedPath);
@ -266,7 +266,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
ProjectWorkspaceState projectWorkspaceState,
IReadOnlyList<DocumentSnapshotHandle> documents)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var normalizedPath = _filePathNormalizer.Normalize(filePath);
var project = (DefaultProjectSnapshot)_projectSnapshotManagerAccessor.Instance.GetLoadedProject(normalizedPath);
@ -411,7 +411,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
// Internal for testing
internal void TryMigrateDocumentsFromRemovedProject(ProjectSnapshot project)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var miscellaneousProject = _projectResolver.GetMiscellaneousProject();
@ -437,7 +437,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem
// Internal for testing
internal void TryMigrateMiscellaneousDocumentsToProject()
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var miscellaneousProject = _projectResolver.GetMiscellaneousProject();

Просмотреть файл

@ -26,20 +26,20 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
internal Timer _documentClosedTimer;
private static readonly TimeSpan s_checkForDocumentClosedDelay = TimeSpan.FromSeconds(5);
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly ITextDocumentLanguageServer _languageServer;
private readonly Dictionary<string, DocumentSnapshot> _work;
private readonly ILogger<RazorDiagnosticsPublisher> _logger;
private ProjectSnapshotManager _projectManager;
public RazorDiagnosticsPublisher(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
ITextDocumentLanguageServer languageServer,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (languageServer == null)
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_languageServer = languageServer;
PublishedDiagnostics = new Dictionary<string, IReadOnlyList<RazorDiagnostic>>(FilePathComparer.Instance);
_work = new Dictionary<string, DocumentSnapshot>(FilePathComparer.Instance);
@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(document));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
lock (_work)
{
@ -114,11 +114,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private async void DocumentClosedTimer_Tick(object state)
#pragma warning restore VSTHRD100 // Avoid async void methods
{
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
ClearClosedDocuments,
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
}
// Internal for testing

Просмотреть файл

@ -22,37 +22,37 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
private SynchronizationCapability _capability;
private readonly ILogger _logger;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly RazorProjectService _projectService;
public RazorDocumentSynchronizationEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
RazorProjectService projectService,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver == null)
if (documentResolver is null)
{
throw new ArgumentNullException(nameof(documentResolver));
}
if (projectService == null)
if (projectService is null)
{
throw new ArgumentNullException(nameof(projectService));
}
if (loggerFactory == null)
if (loggerFactory is null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_projectService = projectService;
_logger = loggerFactory.CreateLogger<RazorDocumentSynchronizationEndpoint>();
@ -67,14 +67,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
public async Task<Unit> Handle(DidChangeTextDocumentParams notification, CancellationToken token)
{
_foregroundDispatcher.AssertBackgroundThread();
var document = await Task.Factory.StartNew(() =>
var document = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(notification.TextDocument.Uri.GetAbsoluteOrUNCPath(), out var documentSnapshot);
return documentSnapshot;
}, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, CancellationToken.None);
var sourceText = await document.GetTextAsync();
sourceText = ApplyContentChanges(notification.ContentChanges, sourceText);
@ -84,19 +82,15 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new InvalidOperationException(RazorLS.Resources.Version_Should_Not_Be_Null);
}
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectService.UpdateDocument(document.FilePath, sourceText, notification.TextDocument.Version.Value),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
return Unit.Value;
}
public async Task<Unit> Handle(DidOpenTextDocumentParams notification, CancellationToken token)
{
_foregroundDispatcher.AssertBackgroundThread();
var sourceText = SourceText.From(notification.TextDocument.Text);
if (notification.TextDocument.Version is null)
@ -104,24 +98,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new InvalidOperationException(RazorLS.Resources.Version_Should_Not_Be_Null);
}
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectService.OpenDocument(notification.TextDocument.Uri.GetAbsoluteOrUNCPath(), sourceText, notification.TextDocument.Version.Value),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
return Unit.Value;
}
public async Task<Unit> Handle(DidCloseTextDocumentParams notification, CancellationToken token)
{
_foregroundDispatcher.AssertBackgroundThread();
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectService.CloseDocument(notification.TextDocument.Uri.GetAbsoluteOrUNCPath()),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
return Unit.Value;
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
// Internal for testing
internal readonly Dictionary<string, DelayedFileChangeNotification> PendingNotifications;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly IEnumerable<IRazorFileChangeListener> _listeners;
private readonly List<FileSystemWatcher> _watchers;
@ -32,13 +32,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
};
public RazorFileChangeDetector(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
FilePathNormalizer filePathNormalizer,
IEnumerable<IRazorFileChangeListener> listeners)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (filePathNormalizer is null)
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(listeners));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_filePathNormalizer = filePathNormalizer;
_listeners = listeners;
_watchers = new List<FileSystemWatcher>(s_razorFileExtensions.Count);
@ -80,13 +80,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
var existingRazorFiles = GetExistingRazorFiles(workspaceDirectory);
await Task.Factory.StartNew(() =>
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
foreach (var razorFilePath in existingRazorFiles)
{
FileSystemWatcher_RazorFileEvent(razorFilePath, RazorFileChangeKind.Added);
}
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
// This is an entry point for testing
OnInitializationFinished();
@ -211,12 +211,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
OnStartingDelayedNotificationWork();
await Task.Factory.StartNew(
() => NotifyAfterDelay_Foreground(physicalFilePath),
CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => NotifyAfterDelay_ProjectSnapshotManagerDispatcher(physicalFilePath),
CancellationToken.None);
}
private void NotifyAfterDelay_Foreground(string physicalFilePath)
private void NotifyAfterDelay_ProjectSnapshotManagerDispatcher(string physicalFilePath)
{
lock (_pendingNotificationsLock)
{

Просмотреть файл

@ -10,16 +10,16 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class RazorFileSynchronizer : IRazorFileChangeListener
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly RazorProjectService _projectService;
public RazorFileSynchronizer(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
RazorProjectService projectService)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (projectService is null)
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(projectService));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_projectService = projectService;
}
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(filePath));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
switch (kind)
{

Просмотреть файл

@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
IRazorMapToDocumentRangesHandler,
IRazorMapToDocumentEditsHandler
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly DocumentVersionCache _documentVersionCache;
private readonly RazorDocumentMappingService _documentMappingService;
@ -31,16 +31,16 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private readonly ILogger _logger;
public RazorLanguageEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
DocumentVersionCache documentVersionCache,
RazorDocumentMappingService documentMappingService,
RazorFormattingService razorFormattingService,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentResolver == null)
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentResolver = documentResolver;
_documentVersionCache = documentVersionCache;
_documentMappingService = documentMappingService;
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
int? documentVersion = null;
DocumentSnapshot documentSnapshot = null;
await Task.Factory.StartNew(() =>
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.Uri.GetAbsoluteOrUNCPath(), out documentSnapshot);
@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
}
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
var codeDocument = await documentSnapshot.GetGeneratedOutputAsync();
var sourceText = await documentSnapshot.GetTextAsync();
@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
int? documentVersion = null;
DocumentSnapshot documentSnapshot = null;
await Task.Factory.StartNew(() =>
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.RazorDocumentUri.GetAbsoluteOrUNCPath(), out documentSnapshot);
@ -166,7 +166,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
documentVersion = null;
}
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
if (request.Kind != RazorLanguageKind.CSharp)
{
@ -215,7 +215,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
int? documentVersion = null;
DocumentSnapshot documentSnapshot = null;
await Task.Factory.StartNew(() =>
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(request.RazorDocumentUri.GetAbsoluteOrUNCPath(), out documentSnapshot);
@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
documentVersion = null;
}
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
var codeDocument = await documentSnapshot.GetGeneratedOutputAsync();
if (codeDocument.IsUnsupported())

Просмотреть файл

@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
// request is made any Parallel requests will be cancelled because the assumption is that Serial requests modify state, and that
// therefore any Parallel request is now invalid and should just try again. A specific instance of this can be seen when you
// hover over a TagHelper while the switch is set to true. Hover is parallel, and a lot of our endpoints like
// textDocument/_ms_onAutoInsert, and razor/languageQuery are Serial. I BELIEVE that specifically what happened is the serial
// textDocument/_vs_onAutoInsert, and razor/languageQuery are Serial. I BELIEVE that specifically what happened is the serial
// languageQuery event gets fired by our semantic tokens endpoint (which fires constantly), cancelling the hover, which red-bars.
// We can prevent that behavior entirely by doing WithContentModifiedSupport, at the possible expense of some delays due doing all requests in serial.
//
@ -122,8 +122,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
.WithHandler<RazorConfigurationEndpoint>()
.WithHandler<RazorFormattingEndpoint>()
.WithHandler<RazorSemanticTokensEndpoint>()
.AddHandlerLink(LanguageServerConstants.RazorSemanticTokensEditEndpoint, LanguageServerConstants.LegacyRazorSemanticTokensEditEndpoint)
.AddHandlerLink(LanguageServerConstants.RazorSemanticTokensEndpoint, LanguageServerConstants.LegacyRazorSemanticTokensEndpoint)
.WithHandler<RazorSemanticTokensLegendEndpoint>()
.WithHandler<OnAutoInsertEndpoint>()
.WithHandler<CodeActionEndpoint>()
@ -138,7 +136,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
.AddLanguageProtocolLogging(logLevel));
services.AddSingleton<FilePathNormalizer>();
services.AddSingleton<ForegroundDispatcher, DefaultForegroundDispatcher>();
services.AddSingleton<ProjectSnapshotManagerDispatcher, DefaultProjectSnapshotManagerDispatcher>();
services.AddSingleton<GeneratedDocumentPublisher, DefaultGeneratedDocumentPublisher>();
services.AddSingleton<AdhocWorkspaceFactory, DefaultAdhocWorkspaceFactory>();
services.AddSingleton<ProjectSnapshotChangeTrigger>((services) => services.GetRequiredService<GeneratedDocumentPublisher>());

Просмотреть файл

@ -11,18 +11,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class RazorServerReadyPublisher : ProjectSnapshotChangeTrigger
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private ProjectSnapshotManagerBase _projectManager;
private readonly ClientNotifierServiceBase _clientNotifierService;
private bool _hasNotified = false;
public RazorServerReadyPublisher(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
ClientNotifierServiceBase clientNotifierService)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (clientNotifierService is null)
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(clientNotifierService));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_clientNotifierService = clientNotifierService;
}
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
private async void ProjectSnapshotManager_Changed(object sender, ProjectChangeEventArgs args)
#pragma warning restore VSTHRD100 // Avoid async void methods
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var projectSnapshot = args.Newer;
if (projectSnapshot?.ProjectWorkspaceState != null && !_hasNotified)

Просмотреть файл

@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring
{
internal class RazorComponentRenameEndpoint : IRenameHandler
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly ProjectSnapshotManager _projectSnapshotManager;
private readonly RazorComponentSearchEngine _componentSearchEngine;
@ -35,13 +35,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring
private RenameCapability _capability;
public RazorComponentRenameEndpoint(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
RazorComponentSearchEngine componentSearchEngine,
ProjectSnapshotManagerAccessor projectSnapshotManagerAccessor,
LanguageServerFeatureOptions languageServerFeatureOptions)
{
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
_componentSearchEngine = componentSearchEngine ?? throw new ArgumentNullException(nameof(componentSearchEngine));
_projectSnapshotManager = projectSnapshotManagerAccessor?.Instance ?? throw new ArgumentNullException(nameof(projectSnapshotManagerAccessor));
@ -70,12 +70,12 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring
return null;
}
var requestDocumentSnapshot = await Task.Factory.StartNew(() =>
var requestDocumentSnapshot = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
var path = request.TextDocument.Uri.GetAbsoluteOrUNCPath();
_documentResolver.TryResolveDocument(path, out var documentSnapshot);
return documentSnapshot;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
if (requestDocumentSnapshot is null)
{
@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring
var documentSnapshots = await GetAllDocumentSnapshotsAsync(requestDocumentSnapshot, cancellationToken).ConfigureAwait(false);
foreach (var documentSnapshot in documentSnapshots)
{
await AddEditsForCodeDocumentAsync(documentChanges, originTagHelpers, request.NewName, documentSnapshot, cancellationToken);
await AddEditsForCodeDocumentAsync(documentChanges, originTagHelpers, request.NewName, documentSnapshot);
}
return new WorkspaceEdit
@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring
private async Task<List<DocumentSnapshot>> GetAllDocumentSnapshotsAsync(DocumentSnapshot skipDocumentSnapshot, CancellationToken cancellationToken)
{
return await Task.Factory.StartNew(() =>
return await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
var documentSnapshots = new List<DocumentSnapshot>();
var documentPaths = new HashSet<string>();
@ -156,7 +156,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring
}
}
return documentSnapshots;
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
}, cancellationToken).ConfigureAwait(false);
}
public void AddFileRenameForComponent(List<WorkspaceEditDocumentChange> documentChanges, DocumentSnapshot documentSnapshot, string newPath)
@ -188,12 +188,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Refactoring
return newPath;
}
public async Task AddEditsForCodeDocumentAsync(
private async Task AddEditsForCodeDocumentAsync(
List<WorkspaceEditDocumentChange> documentChanges,
IReadOnlyList<TagHelperDescriptor> originTagHelpers,
string newName,
DocumentSnapshot documentSnapshot,
CancellationToken cancellationToken)
DocumentSnapshot documentSnapshot)
{
if (documentSnapshot is null)
{

Просмотреть файл

@ -1,17 +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.
#pragma warning disable CS0618
#nullable enable
using OmniSharp.Extensions.LanguageServer.Protocol.Models.Proposals;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic.Models
{
internal class LegacySemanticTokensOptions
{
public SemanticTokensLegend? Legend { get; set; }
public bool RangeProvider { get; set; }
public SemanticTokensDocumentProviderOptions? DocumentProvider { get; set; }
}
}

Просмотреть файл

@ -5,7 +5,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.LanguageServer.Common;
using Microsoft.AspNetCore.Razor.LanguageServer.Semantic.Models;
using Microsoft.Extensions.Logging;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
@ -15,7 +14,7 @@ using OmniSharp.Extensions.LanguageServer.Protocol.Models.Proposals;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic
{
internal class RazorSemanticTokensEndpoint : ISemanticTokensHandler, ISemanticTokensRangeHandler, ISemanticTokensDeltaHandler, IRegistrationExtension
internal class RazorSemanticTokensEndpoint : ISemanticTokensHandler, ISemanticTokensRangeHandler, ISemanticTokensDeltaHandler
{
private SemanticTokensCapability? _capability;
@ -96,19 +95,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic
_capability = capability;
}
public RegistrationExtensionResult GetRegistration()
{
return new RegistrationExtensionResult(LanguageServerConstants.SemanticTokensProviderName, new LegacySemanticTokensOptions
{
DocumentProvider = new SemanticTokensDocumentProviderOptions
{
Edits = true,
},
Legend = RazorSemanticTokensLegend.Instance,
RangeProvider = true,
});
}
private async Task<SemanticTokens?> HandleAsync(TextDocumentIdentifier textDocument, CancellationToken cancellationToken, Range? range = null)
{
var tokens = await _semanticTokensInfoService.GetSemanticTokensAsync(textDocument, range, cancellationToken);

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic
private readonly MemoryCache<string, IReadOnlyList<int>> _csharpGeneratedSemanticTokensCache = new(); // For C# generated docs
private readonly ClientNotifierServiceBase _languageServer;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentResolver _documentResolver;
private readonly DocumentVersionCache _documentVersionCache;
private readonly ILogger _logger;
@ -43,14 +43,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic
public DefaultRazorSemanticTokensInfoService(
ClientNotifierServiceBase languageServer,
RazorDocumentMappingService documentMappingService,
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentResolver documentResolver,
DocumentVersionCache documentVersionCache,
ILoggerFactory loggerFactory)
{
_languageServer = languageServer ?? throw new ArgumentNullException(nameof(languageServer));
_documentMappingService = documentMappingService ?? throw new ArgumentNullException(nameof(documentMappingService));
_foregroundDispatcher = foregroundDispatcher ?? throw new ArgumentNullException(nameof(foregroundDispatcher));
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher ?? throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
_documentResolver = documentResolver ?? throw new ArgumentNullException(nameof(documentResolver));
_documentVersionCache = documentVersionCache ?? throw new ArgumentNullException(nameof(documentVersionCache));
@ -561,13 +561,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic
private async Task<(DocumentSnapshot Snapshot, int? Version)> TryGetDocumentInfoAsync(string absolutePath, CancellationToken cancellationToken)
{
var documentInfo = await Task.Factory.StartNew(() =>
var documentInfo = await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(() =>
{
_documentResolver.TryResolveDocument(absolutePath, out var documentSnapshot);
_documentVersionCache.TryGetDocumentVersion(documentSnapshot, out var version);
return (documentSnapshot, version);
}, cancellationToken, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
}, cancellationToken);
return documentInfo;
}

Просмотреть файл

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Tooltip
/// </summary>
internal sealed class VSClassifiedTextElement
{
[JsonProperty("type")]
[JsonProperty("_vs_type")]
public static readonly string Type = "ClassifiedTextElement";
public const string TextClassificationTypeName = "text";

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Tooltip
/// </summary>
internal sealed class VSClassifiedTextRun
{
[JsonProperty("type")]
[JsonProperty("_vs_type")]
public static readonly string Type = "ClassifiedTextRun";
public VSClassifiedTextRun(string classificationTypeName, string text)

Просмотреть файл

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Tooltip
/// </summary>
internal sealed class VSContainerElement
{
[JsonProperty("type")]
[JsonProperty("_vs_type")]
public static readonly string Type = "ContainerElement";
public VSContainerElement(VSContainerElementStyle style, IEnumerable<object> elements)

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Tooltip
/// </summary>
internal class VSImageElement
{
[JsonProperty("type")]
[JsonProperty("_vs_type")]
public static readonly string Type = "ImageElement";
public static readonly VSImageElement Empty = new(default, string.Empty);

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Tooltip
/// </summary>
internal class VSImageId : IEquatable<VSImageId>
{
[JsonProperty("type")]
[JsonProperty("_vs_type")]
public static readonly string Type = "ImageId";
[JsonProperty("Guid")]

Просмотреть файл

@ -9,19 +9,19 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class UnsynchronizableContentDocumentProcessedListener : DocumentProcessedListener
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly DocumentVersionCache _documentVersionCache;
private readonly GeneratedDocumentPublisher _generatedDocumentPublisher;
private ProjectSnapshotManager _projectManager;
public UnsynchronizableContentDocumentProcessedListener(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
DocumentVersionCache documentVersionCache,
GeneratedDocumentPublisher generatedDocumentPublisher)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (documentVersionCache == null)
@ -34,14 +34,14 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
throw new ArgumentNullException(nameof(generatedDocumentPublisher));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_documentVersionCache = documentVersionCache;
_generatedDocumentPublisher = generatedDocumentPublisher;
}
public override void DocumentProcessed(DocumentSnapshot document)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (!_projectManager.IsDocumentOpen(document.FilePath))
{

Просмотреть файл

@ -1,24 +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.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.LanguageServer.Common;
namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
{
public class DefaultOmniSharpForegroundDispatcher : OmniSharpForegroundDispatcher
{
public DefaultOmniSharpForegroundDispatcher()
{
InternalDispatcher = new DefaultForegroundDispatcher();
}
public override bool IsForegroundThread => InternalDispatcher.IsForegroundThread;
public override TaskScheduler ForegroundScheduler => InternalDispatcher.ForegroundScheduler;
public override TaskScheduler BackgroundScheduler => InternalDispatcher.BackgroundScheduler;
public override void AssertBackgroundThread([CallerMemberName] string caller = null) => InternalDispatcher.AssertBackgroundThread(caller);
public override void AssertForegroundThread([CallerMemberName] string caller = null) => InternalDispatcher.AssertForegroundThread(caller);
}
}

Просмотреть файл

@ -15,14 +15,14 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
{
private readonly RemoteTextLoaderFactory _remoteTextLoaderFactory;
private readonly IEnumerable<IOmniSharpProjectSnapshotManagerChangeTrigger> _projectChangeTriggers;
private readonly OmniSharpForegroundDispatcher _foregroundDispatcher;
private readonly OmniSharpProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly Workspace _workspace;
private OmniSharpProjectSnapshotManager _instance;
public DefaultOmniSharpProjectSnapshotManagerAccessor(
RemoteTextLoaderFactory remoteTextLoaderFactory,
IEnumerable<IOmniSharpProjectSnapshotManagerChangeTrigger> projectChangeTriggers,
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
Workspace workspace)
{
if (remoteTextLoaderFactory is null)
@ -35,9 +35,9 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
throw new ArgumentNullException(nameof(projectChangeTriggers));
}
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (workspace == null)
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
_remoteTextLoaderFactory = remoteTextLoaderFactory;
_projectChangeTriggers = projectChangeTriggers;
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_workspace = workspace;
}
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
if (_instance == null)
{
var projectSnapshotManager = new DefaultProjectSnapshotManager(
_foregroundDispatcher.InternalDispatcher,
_projectSnapshotManagerDispatcher.InternalDispatcher,
new DefaultErrorReporter(),
Enumerable.Empty<ProjectSnapshotChangeTrigger>(),
_workspace);

Просмотреть файл

@ -0,0 +1,21 @@
// 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.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor.Workspaces;
namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
{
public class DefaultOmniSharpProjectSnapshotManagerDispatcher : OmniSharpProjectSnapshotManagerDispatcher
{
public DefaultOmniSharpProjectSnapshotManagerDispatcher()
{
InternalDispatcher = new DefaultProjectSnapshotManagerDispatcher();
}
public override TaskScheduler DispatcherScheduler => InternalDispatcher.DispatcherScheduler;
public override void AssertDispatcherThread([CallerMemberName] string caller = null) => InternalDispatcher.AssertDispatcherThread(caller);
}
}

Просмотреть файл

@ -15,13 +15,13 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
private readonly BackgroundDocumentGenerator _backgroundDocumentGenerator;
public OmniSharpBackgroundDocumentGenerator(
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
RemoteTextLoaderFactory remoteTextLoaderFactory,
IEnumerable<OmniSharpDocumentProcessedListener> documentProcessedListeners)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (remoteTextLoaderFactory is null)
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
}
var wrappedListeners = documentProcessedListeners.Select(listener => new WrappedDocumentProcessedListener(remoteTextLoaderFactory, listener));
_backgroundDocumentGenerator = new BackgroundDocumentGenerator(foregroundDispatcher.InternalDispatcher, wrappedListeners);
_backgroundDocumentGenerator = new BackgroundDocumentGenerator(projectSnapshotManagerDispatcher.InternalDispatcher, wrappedListeners);
}
public void Initialize(OmniSharpProjectSnapshotManagerBase projectManager)

Просмотреть файл

@ -1,24 +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.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
{
public abstract class OmniSharpForegroundDispatcher
{
internal ForegroundDispatcher InternalDispatcher { get; private protected set; }
public abstract bool IsForegroundThread { get; }
public abstract TaskScheduler ForegroundScheduler { get; }
public abstract TaskScheduler BackgroundScheduler { get; }
public abstract void AssertForegroundThread([CallerMemberName] string caller = null);
public abstract void AssertBackgroundThread([CallerMemberName] string caller = null);
}
}

Просмотреть файл

@ -0,0 +1,26 @@
// 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 System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
{
public abstract class OmniSharpProjectSnapshotManagerDispatcher
{
internal ProjectSnapshotManagerDispatcher InternalDispatcher { get; private protected set; }
public abstract TaskScheduler DispatcherScheduler { get; }
public Task RunOnDispatcherThreadAsync(Action action, CancellationToken cancellationToken)
=> InternalDispatcher.RunOnDispatcherThreadAsync(action, cancellationToken);
public Task<TResult> RunOnDispatcherThreadAsync<TResult>(Func<TResult> action, CancellationToken cancellationToken)
=> InternalDispatcher.RunOnDispatcherThreadAsync(action, cancellationToken);
public abstract void AssertDispatcherThread([CallerMemberName] string caller = null);
}
}

Просмотреть файл

@ -15,14 +15,14 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
{
}
public OmniSharpProjectWorkspaceStateGenerator(OmniSharpForegroundDispatcher foregroundDispatcher)
public OmniSharpProjectWorkspaceStateGenerator(OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
InternalWorkspaceStateGenerator = new DefaultProjectWorkspaceStateGenerator(foregroundDispatcher.InternalDispatcher);
InternalWorkspaceStateGenerator = new DefaultProjectWorkspaceStateGenerator(projectSnapshotManagerDispatcher.InternalDispatcher);
}
internal DefaultProjectWorkspaceStateGenerator InternalWorkspaceStateGenerator { get; }

Просмотреть файл

@ -4,7 +4,6 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
@ -14,12 +13,12 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
public class OmniSharpWorkspaceProjectStateChangeDetector : IOmniSharpProjectSnapshotManagerChangeTrigger
{
public OmniSharpWorkspaceProjectStateChangeDetector(
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
OmniSharpProjectWorkspaceStateGenerator workspaceStateGenerator)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (workspaceStateGenerator == null)
@ -27,8 +26,8 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
throw new ArgumentNullException(nameof(workspaceStateGenerator));
}
InternalWorkspaceProjectStateChangeDetector = new ForegroundWorkspaceProjectStateChangeDetector(
foregroundDispatcher.InternalDispatcher,
InternalWorkspaceProjectStateChangeDetector = new ProjectSnapshotManagerWorkspaceProjectStateChangeDetector(
projectSnapshotManagerDispatcher.InternalDispatcher,
workspaceStateGenerator.InternalWorkspaceStateGenerator);
}
@ -39,37 +38,31 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
InternalWorkspaceProjectStateChangeDetector.Initialize(projectManager.InternalProjectSnapshotManager);
}
private class ForegroundWorkspaceProjectStateChangeDetector : WorkspaceProjectStateChangeDetector
private class ProjectSnapshotManagerWorkspaceProjectStateChangeDetector : WorkspaceProjectStateChangeDetector
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
public ForegroundWorkspaceProjectStateChangeDetector(
ForegroundDispatcher foregroundDispatcher,
ProjectWorkspaceStateGenerator workspaceStateGenerator) : base(workspaceStateGenerator)
public ProjectSnapshotManagerWorkspaceProjectStateChangeDetector(
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
ProjectWorkspaceStateGenerator workspaceStateGenerator) : base(workspaceStateGenerator, projectSnapshotManagerDispatcher)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
}
// We override the InitializeSolution in order to enforce calls to this to be on the foreground thread.
// OmniSharp currently has an issue where they update the Solution on multiple different threads resulting
// We override the InitializeSolution in order to enforce calls to this to be on the project snapshot manager's
// thread. OmniSharp currently has an issue where they update the Solution on multiple different threads resulting
// in change events dispatching through the Workspace on multiple different threads. This normalizes
// that abnormality.
#pragma warning disable VSTHRD100 // Avoid async void methods
protected override async void InitializeSolution(Solution solution)
#pragma warning restore VSTHRD100 // Avoid async void methods
{
if (_foregroundDispatcher.IsForegroundThread)
{
base.InitializeSolution(solution);
return;
}
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() =>
{
try
@ -81,25 +74,18 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
Debug.Fail("Unexpected error when initializing solution: " + ex);
}
},
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
}
// We override Workspace_WorkspaceChanged in order to enforce calls to this to be on the foreground thread.
// OmniSharp currently has an issue where they update the Solution on multiple different threads resulting
// We override Workspace_WorkspaceChanged in order to enforce calls to this to be on the project snapshot manager's
// thread. OmniSharp currently has an issue where they update the Solution on multiple different threads resulting
// in change events dispatching through the Workspace on multiple different threads. This normalizes
// that abnormality.
#pragma warning disable VSTHRD100 // Avoid async void methods
internal override async void Workspace_WorkspaceChanged(object sender, WorkspaceChangeEventArgs args)
#pragma warning restore VSTHRD100 // Avoid async void methods
{
if (_foregroundDispatcher.IsForegroundThread)
{
base.Workspace_WorkspaceChanged(sender, args);
return;
}
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() =>
{
try
@ -111,9 +97,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin.StrongNamed
Debug.Fail("Unexpected error when handling a workspace changed event: " + ex);
}
},
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler);
CancellationToken.None);
}
}
}

Просмотреть файл

@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
internal const string ActiveVirtualDocumentSuffix = "__virtual.cs";
internal const string BackgroundVirtualDocumentSuffix = "__bg" + ActiveVirtualDocumentSuffix;
private readonly OmniSharpForegroundDispatcher _foregroundDispatcher;
private readonly OmniSharpProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly OmniSharpWorkspace _workspace;
private readonly ILogger _logger;
private OmniSharpProjectSnapshotManager _projectManager;
@ -43,13 +43,13 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
[ImportingConstructor]
public BackgroundDocumentProcessedPublisher(
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
OmniSharpWorkspace workspace,
ILoggerFactory loggerFactory)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (workspace is null)
@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
throw new ArgumentNullException(nameof(loggerFactory));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_workspace = workspace;
_logger = loggerFactory.CreateLogger<BackgroundDocumentProcessedPublisher>();
_workspaceChangedLock = new object();
@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
throw new ArgumentNullException(nameof(document));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
lock (_workspaceChangedLock)
{

Просмотреть файл

@ -35,31 +35,22 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
private const string RazorGenerateDesignTimeTargetName = "RazorGenerateDesignTime";
private const string RazorGenerateComponentDesignTimeTargetName = "RazorGenerateComponentDesignTime";
private static readonly IEnumerable<ILogger> s_emptyMSBuildLoggers = Enumerable.Empty<ILogger>();
private readonly OmniSharpForegroundDispatcher _foregroundDispatcher;
private readonly object _evaluationLock = new object();
[ImportingConstructor]
public DefaultProjectInstanceEvaluator(OmniSharpForegroundDispatcher foregroundDispatcher)
public DefaultProjectInstanceEvaluator()
{
if (foregroundDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
}
_foregroundDispatcher = foregroundDispatcher;
}
public override ProjectInstance Evaluate(ProjectInstance projectInstance)
{
if (projectInstance == null)
if (projectInstance is null)
{
throw new ArgumentNullException(nameof(projectInstance));
}
lock (_evaluationLock)
{
_foregroundDispatcher.AssertBackgroundThread();
var refreshTargets = new List<string>()
{
// These are the default targets for the project instance that OmniSharp runs.

Просмотреть файл

@ -4,7 +4,6 @@
using System;
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.OmniSharpPlugin;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
@ -14,18 +13,18 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
[Export(typeof(IOmniSharpProjectSnapshotManagerChangeTrigger))]
internal class DocumentChangedSynchronizationService : IRazorDocumentChangeListener, IOmniSharpProjectSnapshotManagerChangeTrigger
{
private readonly OmniSharpForegroundDispatcher _foregroundDispatcher;
private readonly OmniSharpProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private OmniSharpProjectSnapshotManagerBase _projectManager;
[ImportingConstructor]
public DocumentChangedSynchronizationService(OmniSharpForegroundDispatcher foregroundDispatcher)
public DocumentChangedSynchronizationService(OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher)
{
if (foregroundDispatcher is null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
}
public void Initialize(OmniSharpProjectSnapshotManagerBase projectManager)
@ -53,9 +52,9 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
var projectFilePath = args.UnevaluatedProjectInstance.ProjectFileLocation.File;
var documentFilePath = args.FilePath;
_ = Task.Factory.StartNew(
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectManager.DocumentChanged(projectFilePath, documentFilePath),
CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
CancellationToken.None).ConfigureAwait(false);
}
}
}

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Razor.OmnisharpPlugin
private readonly IEnumerable<ProjectConfigurationProvider> _projectConfigurationProviders;
private readonly ProjectInstanceEvaluator _projectInstanceEvaluator;
private readonly ProjectChangePublisher _projectConfigurationPublisher;
private readonly OmniSharpForegroundDispatcher _foregroundDispatcher;
private readonly OmniSharpProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private OmniSharpProjectSnapshotManagerBase _projectManager;
[ImportingConstructor]
@ -42,30 +42,30 @@ namespace Microsoft.AspNetCore.Razor.OmnisharpPlugin
[ImportMany] IEnumerable<ProjectConfigurationProvider> projectConfigurationProviders,
ProjectInstanceEvaluator projectInstanceEvaluator,
ProjectChangePublisher projectConfigurationPublisher,
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
ILoggerFactory loggerFactory)
{
if (projectConfigurationProviders == null)
if (projectConfigurationProviders is null)
{
throw new ArgumentNullException(nameof(projectConfigurationProviders));
}
if (projectInstanceEvaluator == null)
if (projectInstanceEvaluator is null)
{
throw new ArgumentNullException(nameof(projectInstanceEvaluator));
}
if (projectConfigurationPublisher == null)
if (projectConfigurationPublisher is null)
{
throw new ArgumentNullException(nameof(projectConfigurationPublisher));
}
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (loggerFactory == null)
if (loggerFactory is null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Razor.OmnisharpPlugin
_projectConfigurationProviders = projectConfigurationProviders;
_projectInstanceEvaluator = projectInstanceEvaluator;
_projectConfigurationPublisher = projectConfigurationPublisher;
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
}
public void Initialize(OmniSharpProjectSnapshotManagerBase projectManager)
@ -103,19 +103,14 @@ namespace Microsoft.AspNetCore.Razor.OmnisharpPlugin
public void RazorDocumentChanged(RazorFileChangeEventArgs args)
{
_foregroundDispatcher.AssertBackgroundThread();
if (args.Kind == RazorFileChangeKind.Added ||
args.Kind == RazorFileChangeKind.Removed)
{
// When documents get added or removed we need to refresh project state to properly reflect the host documents in the project.
var evaluatedProjectInstance = _projectInstanceEvaluator.Evaluate(args.UnevaluatedProjectInstance);
_ = Task.Factory.StartNew(
() => UpdateProjectState(evaluatedProjectInstance),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => UpdateProjectState(evaluatedProjectInstance), CancellationToken.None).ConfigureAwait(false);
}
}
@ -142,13 +137,13 @@ namespace Microsoft.AspNetCore.Razor.OmnisharpPlugin
// Force project instance evaluation to ensure that all Razor specific targets have run.
projectInstance = _projectInstanceEvaluator.Evaluate(projectInstance);
await Task.Factory.StartNew(() => UpdateProjectState(projectInstance),
CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => UpdateProjectState(projectInstance), CancellationToken.None);
}
private void UpdateProjectState(ProjectInstance projectInstance)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var projectFilePath = projectInstance.GetPropertyValue(MSBuildProjectFullPathPropertyName);
if (string.IsNullOrEmpty(projectFilePath))

Просмотреть файл

@ -13,9 +13,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="$(Tooling_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion)" />
<PackageReference Include="OmniSharp.MSBuild" Version="$(OmniSharpMSBuildPackageVersion)" />
<PackageReference Include="Microsoft.Build" Version="$(MicrosoftBuildPackageVersion)" ExcludeAssets="Runtime" PrivateAssets="All" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="$(Tooling_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.ExternalAccess.OmniSharp.CSharp" Version="$(Tooling_MicrosoftCodeAnalysisExternalAccessOmniSharpCSharpPackageVersion)" />
</ItemGroup>
</Project>

Просмотреть файл

@ -21,8 +21,8 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
}
[Shared]
[Export(typeof(OmniSharpForegroundDispatcher))]
internal class ExportOmniSharpForegroundDispatcher : DefaultOmniSharpForegroundDispatcher
[Export(typeof(OmniSharpProjectSnapshotManagerDispatcher))]
internal class ExportOmniSharpProjectSnapshotManagerDispatcher : DefaultOmniSharpProjectSnapshotManagerDispatcher
{
}
@ -44,8 +44,8 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
public ExportDefaultOmniSharpProjectSnapshotManagerAccessor(
RemoteTextLoaderFactory remoteTextLoaderFactory,
[ImportMany] IEnumerable<IOmniSharpProjectSnapshotManagerChangeTrigger> projectChangeTriggers,
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpWorkspace workspace) : base(remoteTextLoaderFactory, projectChangeTriggers, foregroundDispatcher, workspace)
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
OmniSharpWorkspace workspace) : base(remoteTextLoaderFactory, projectChangeTriggers, projectSnapshotManagerDispatcher, workspace)
{
}
}
@ -56,8 +56,8 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
{
[ImportingConstructor]
public ExportOmniSharpWorkspaceProjectStateChangeDetector(
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectWorkspaceStateGenerator workspaceStateGenerator) : base(foregroundDispatcher, workspaceStateGenerator)
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
OmniSharpProjectWorkspaceStateGenerator workspaceStateGenerator) : base(projectSnapshotManagerDispatcher, workspaceStateGenerator)
{
}
}
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
public class ExportOmniSharpProjectWorkspaceStateGenerator : OmniSharpProjectWorkspaceStateGenerator
{
[ImportingConstructor]
public ExportOmniSharpProjectWorkspaceStateGenerator(OmniSharpForegroundDispatcher foregroundDispatcher) : base(foregroundDispatcher)
public ExportOmniSharpProjectWorkspaceStateGenerator(OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher) : base(projectSnapshotManagerDispatcher)
{
}
}
@ -79,9 +79,9 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
{
[ImportingConstructor]
public ExportOmniSharpBackgroundDocumentGenerator(
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
RemoteTextLoaderFactory remoteTextLoaderFactory,
[ImportMany] IEnumerable<OmniSharpDocumentProcessedListener> documentProcessedListeners) : base(foregroundDispatcher, remoteTextLoaderFactory, documentProcessedListeners)
[ImportMany] IEnumerable<OmniSharpDocumentProcessedListener> documentProcessedListeners) : base(projectSnapshotManagerDispatcher, remoteTextLoaderFactory, documentProcessedListeners)
{
}
}

Просмотреть файл

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
[Export(typeof(IOmniSharpProjectSnapshotManagerChangeTrigger))]
internal class TagHelperRefreshTrigger : IMSBuildEventSink, IRazorDocumentOutputChangeListener, IOmniSharpProjectSnapshotManagerChangeTrigger, IRazorDocumentChangeListener
{
private readonly OmniSharpForegroundDispatcher _foregroundDispatcher;
private readonly OmniSharpProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly Workspace _omniSharpWorkspace;
private readonly OmniSharpProjectWorkspaceStateGenerator _workspaceStateGenerator;
private readonly Dictionary<string, Task> _deferredUpdates;
@ -30,22 +30,22 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
[ImportingConstructor]
public TagHelperRefreshTrigger(
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
OmniSharpWorkspace omniSharpWorkspace,
OmniSharpProjectWorkspaceStateGenerator workspaceStateGenerator) :
this(foregroundDispatcher, (Workspace)omniSharpWorkspace, workspaceStateGenerator)
this(projectSnapshotManagerDispatcher, (Workspace)omniSharpWorkspace, workspaceStateGenerator)
{
}
// Internal for testing
internal TagHelperRefreshTrigger(
OmniSharpForegroundDispatcher foregroundDispatcher,
OmniSharpProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
Workspace omniSharpWorkspace,
OmniSharpProjectWorkspaceStateGenerator workspaceStateGenerator)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (omniSharpWorkspace == null)
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
throw new ArgumentNullException(nameof(workspaceStateGenerator));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_omniSharpWorkspace = omniSharpWorkspace;
_workspaceStateGenerator = workspaceStateGenerator;
_deferredUpdates = new Dictionary<string, Task>();
@ -85,11 +85,9 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
// Project file was modified or impacted in a significant way.
_ = Task.Factory.StartNew(
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => EnqueueUpdate(args.ProjectInstance.ProjectFileLocation.File),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
CancellationToken.None).ConfigureAwait(false);
}
public void RazorDocumentChanged(RazorFileChangeEventArgs args)
@ -113,7 +111,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
},
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
_projectSnapshotManagerDispatcher.DispatcherScheduler).ConfigureAwait(false);
}
public void RazorDocumentOutputChanged(RazorFileChangeEventArgs args)
@ -129,7 +127,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
() => EnqueueUpdate(args.UnevaluatedProjectInstance.ProjectFileLocation.File),
CancellationToken.None,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
_projectSnapshotManagerDispatcher.DispatcherScheduler).ConfigureAwait(false);
}
// Internal for testing
@ -152,7 +150,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
private void EnqueueUpdate(string projectFilePath)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
// A race is not possible here because we use the main thread to synchronize the updates
// by capturing the sync context.
@ -177,7 +175,7 @@ namespace Microsoft.AspNetCore.Razor.OmniSharpPlugin
// Internal for testing
internal bool IsComponentFile(string relativeDocumentFilePath, string projectFilePath)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var projectSnapshot = _projectManager.GetLoadedProject(projectFilePath);
if (projectSnapshot == null)

Просмотреть файл

@ -3,9 +3,8 @@
using System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.Editor.Razor
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
[ExportCustomProjectEngineFactory("Default", SupportsSerialization = true)]
internal class DefaultProjectEngineFactory : IProjectEngineFactory

Просмотреть файл

@ -5,26 +5,24 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
internal class DefaultForegroundDispatcher : ForegroundDispatcher
internal class DefaultProjectSnapshotManagerDispatcher : ProjectSnapshotManagerDispatcher
{
public override bool IsForegroundThread => Thread.CurrentThread.ManagedThreadId == ForegroundTaskScheduler.Instance.ForegroundThreadId;
public override bool IsDispatcherThread
=> Thread.CurrentThread.ManagedThreadId == ProjectSnapshotManagerTaskScheduler.Instance.ThreadId;
public override TaskScheduler ForegroundScheduler { get; } = ForegroundTaskScheduler.Instance;
public override TaskScheduler DispatcherScheduler { get; } = ProjectSnapshotManagerTaskScheduler.Instance;
public override TaskScheduler BackgroundScheduler { get; } = TaskScheduler.Default;
internal class ForegroundTaskScheduler : TaskScheduler
internal class ProjectSnapshotManagerTaskScheduler : TaskScheduler
{
public static ForegroundTaskScheduler Instance = new ForegroundTaskScheduler();
public static ProjectSnapshotManagerTaskScheduler Instance = new();
private readonly Thread _thread;
private readonly BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
private readonly BlockingCollection<Task> _tasks = new();
private ForegroundTaskScheduler()
private ProjectSnapshotManagerTaskScheduler()
{
_thread = new Thread(ThreadStart)
{
@ -34,7 +32,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Common
_thread.Start();
}
public int ForegroundThreadId => _thread.ManagedThreadId;
public int ThreadId => _thread.ManagedThreadId;
public override int MaximumConcurrencyLevel => 1;

Просмотреть файл

@ -20,21 +20,21 @@ namespace Microsoft.CodeAnalysis.Razor
// Internal for testing
internal readonly Dictionary<string, UpdateItem> Updates;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly SemaphoreSlim _semaphore;
private ProjectSnapshotManagerBase _projectManager;
private TagHelperResolver _tagHelperResolver;
private bool _disposed;
[ImportingConstructor]
public DefaultProjectWorkspaceStateGenerator(ForegroundDispatcher foregroundDispatcher)
public DefaultProjectWorkspaceStateGenerator(ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_semaphore = new SemaphoreSlim(initialCount: 1);
Updates = new Dictionary<string, UpdateItem>(FilePathComparer.Instance);
@ -65,7 +65,7 @@ namespace Microsoft.CodeAnalysis.Razor
throw new ArgumentNullException(nameof(projectSnapshot));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_disposed)
{
@ -89,7 +89,7 @@ namespace Microsoft.CodeAnalysis.Razor
() => UpdateWorkspaceStateAsync(workspaceProject, projectSnapshot, lcts.Token),
lcts.Token,
TaskCreationOptions.None,
_foregroundDispatcher.BackgroundScheduler).Unwrap();
TaskScheduler.Default).Unwrap();
updateTask.ConfigureAwait(false);
updateItem = new UpdateItem(updateTask, lcts);
Updates[projectSnapshot.FilePath] = updateItem;
@ -97,8 +97,6 @@ namespace Microsoft.CodeAnalysis.Razor
public void Dispose()
{
_foregroundDispatcher.AssertForegroundThread();
_disposed = true;
foreach (var update in Updates)
@ -132,8 +130,6 @@ namespace Microsoft.CodeAnalysis.Razor
try
{
_foregroundDispatcher.AssertBackgroundThread();
OnStartingBackgroundWork();
if (cancellationToken.IsCancellationRequested)
@ -168,11 +164,10 @@ namespace Microsoft.CodeAnalysis.Razor
}
catch (Exception ex)
{
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectManager.ReportError(ex, projectSnapshot),
CancellationToken.None, // Don't allow errors to be cancelled
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
// Don't allow errors to be cancelled
CancellationToken.None).ConfigureAwait(false);
return;
}
@ -182,7 +177,7 @@ namespace Microsoft.CodeAnalysis.Razor
return;
}
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() =>
{
if (cancellationToken.IsCancellationRequested)
@ -192,9 +187,7 @@ namespace Microsoft.CodeAnalysis.Razor
ReportWorkspaceStateChange(projectSnapshot.FilePath, workspaceState);
},
cancellationToken,
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
@ -204,11 +197,10 @@ namespace Microsoft.CodeAnalysis.Razor
catch (Exception ex)
{
// This is something totally unexpected, let's just send it over to the project manager.
await Task.Factory.StartNew(
await _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => _projectManager.ReportError(ex),
CancellationToken.None, // Don't allow errors to be cancelled
TaskCreationOptions.None,
_foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
// Don't allow errors to be cancelled
CancellationToken.None).ConfigureAwait(false);
}
finally
{
@ -227,7 +219,7 @@ namespace Microsoft.CodeAnalysis.Razor
private void ReportWorkspaceStateChange(string projectFilePath, ProjectWorkspaceState workspaceStateChange)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
_projectManager.ProjectWorkspaceStateChanged(projectFilePath, workspaceStateChange);
}

Просмотреть файл

@ -1,36 +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;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Razor
{
internal abstract class ForegroundDispatcher
{
public abstract bool IsForegroundThread { get; }
public abstract TaskScheduler ForegroundScheduler { get; }
public abstract TaskScheduler BackgroundScheduler { 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));
}
}
}
}

Просмотреть файл

@ -0,0 +1,21 @@
// 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.VisualStudio.Threading;
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
internal static class JoinableTaskContextExtensions
{
public static void AssertUIThread(this JoinableTaskContext joinableTaskContext, [CallerMemberName] string caller = null)
{
if (!joinableTaskContext.IsOnMainThread)
{
caller = caller is null ? "The method" : $"'{caller}'";
throw new InvalidOperationException($"{caller} must be called on the UI thread.");
}
}
}
}

Просмотреть файл

@ -4,9 +4,8 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.Editor.Razor
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
[ExportCustomProjectEngineFactory("MVC-1.0", SupportsSerialization = true)]
internal class LegacyProjectEngineFactory_1_0 : IProjectEngineFactory

Просмотреть файл

@ -4,9 +4,8 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.Editor.Razor
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
[ExportCustomProjectEngineFactory("MVC-1.1", SupportsSerialization = true)]
internal class LegacyProjectEngineFactory_1_1 : IProjectEngineFactory

Просмотреть файл

@ -4,9 +4,8 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.Editor.Razor
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
[ExportCustomProjectEngineFactory("MVC-2.0", SupportsSerialization = true)]
internal class LegacyProjectEngineFactory_2_0 : IProjectEngineFactory

Просмотреть файл

@ -4,9 +4,8 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.Editor.Razor
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
// Currently we provide a fixed configuration for 2.1, but this is a point-in-time issue. We plan
// to make the 2.1 configuration more flexible and less hardcoded.

Просмотреть файл

@ -4,9 +4,8 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor;
namespace Microsoft.VisualStudio.Editor.Razor
namespace Microsoft.CodeAnalysis.Razor.Workspaces
{
[ExportCustomProjectEngineFactory("MVC-3.0", SupportsSerialization = true)]
internal class LegacyProjectEngineFactory_3_0 : IProjectEngineFactory

Просмотреть файл

@ -14,6 +14,9 @@
<PackageReference Include="Microsoft.CodeAnalysis.Razor" Version="$(MicrosoftCodeAnalysisRazorPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.ExternalAccess.Razor" Version="$(Tooling_MicrosoftCodeAnalysisExternalAccessRazorPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="$(Tooling_MicrosoftCodeAnalysisWorkspacesCommonPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X" Version="$(MicrosoftAspNetCoreMvcRazorExtensionsVersion1_XPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X" Version="$(MicrosoftAspNetCoreMvcRazorExtensionsVersion2_XPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="$(MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.NonCapturingTimer.Sources" Version="$(MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion)" PrivateAssets="all" />
</ItemGroup>

Просмотреть файл

@ -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 System.Threading;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Razor
{
internal abstract class ProjectSnapshotManagerDispatcher
{
public abstract bool IsDispatcherThread { get; }
public abstract TaskScheduler DispatcherScheduler { get; }
public Task RunOnDispatcherThreadAsync(Action action, CancellationToken cancellationToken)
=> Task.Factory.StartNew(action, cancellationToken, TaskCreationOptions.None, DispatcherScheduler);
public Task<TResult> RunOnDispatcherThreadAsync<TResult>(Func<TResult> action, CancellationToken cancellationToken)
=> Task.Factory.StartNew(action, cancellationToken, TaskCreationOptions.None, DispatcherScheduler);
public virtual void AssertDispatcherThread([CallerMemberName] string caller = null)
{
if (!IsDispatcherThread)
{
caller = caller is null ? "The method" : $"'{caller}'";
throw new InvalidOperationException(caller + " must be called on the project snapshot manager's thread.");
}
}
}
}

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
public override event EventHandler<ProjectChangeEventArgs> Changed;
private readonly ErrorReporter _errorReporter;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
private readonly ProjectSnapshotChangeTrigger[] _triggers;
// Each entry holds a ProjectState and an optional ProjectSnapshot. ProjectSnapshots are
@ -33,32 +33,32 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
private readonly Queue<ProjectChangeEventArgs> _notificationWork;
public DefaultProjectSnapshotManager(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
ErrorReporter errorReporter,
IEnumerable<ProjectSnapshotChangeTrigger> triggers,
Workspace workspace)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher is null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (errorReporter == null)
if (errorReporter is null)
{
throw new ArgumentNullException(nameof(errorReporter));
}
if (triggers == null)
if (triggers is null)
{
throw new ArgumentNullException(nameof(triggers));
}
if (workspace == null)
if (workspace is null)
{
throw new ArgumentNullException(nameof(workspace));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_errorReporter = errorReporter;
_triggers = triggers.OrderByDescending(trigger => trigger.InitializePriority).ToArray();
Workspace = workspace;
@ -67,9 +67,28 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
_openDocuments = new HashSet<string>(FilePathComparer.Instance);
_notificationWork = new Queue<ProjectChangeEventArgs>();
for (var i = 0; i < _triggers.Length; i++)
// All methods involving the project snapshot manager need to be run on the
// project snapshot manager's specialized thread. The LSP editor should already
// be on the specialized thread, however the old editor may be calling this
// constructor on the UI thread.
if (_projectSnapshotManagerDispatcher.IsDispatcherThread)
{
_triggers[i].Initialize(this);
InitializeTriggers(this, _triggers);
}
else
{
_ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
() => InitializeTriggers(this, _triggers), CancellationToken.None);
}
static void InitializeTriggers(
DefaultProjectSnapshotManager snapshotManager,
ProjectSnapshotChangeTrigger[] triggers)
{
for (var i = 0; i < triggers.Length; i++)
{
triggers[i].Initialize(snapshotManager);
}
}
}
@ -77,7 +96,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
{
get
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
var i = 0;
var projects = new ProjectSnapshot[_projects.Count];
@ -94,7 +113,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
{
get
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
return _openDocuments;
}
@ -109,7 +128,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(filePath));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(filePath, out var entry))
{
@ -126,7 +145,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(filePath));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
return GetLoadedProject(filePath) ?? new EphemeralProjectSnapshot(Workspace.Services, filePath);
}
@ -138,7 +157,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(documentFilePath));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
return _openDocuments.Contains(documentFilePath);
}
@ -155,7 +174,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(document));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(hostProject.FilePath, out var entry))
{
@ -187,7 +206,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(document));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(hostProject.FilePath, out var entry))
{
var state = entry.State.WithRemovedHostDocument(document);
@ -220,7 +240,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(sourceText));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(projectFilePath, out var entry) &&
entry.State.Documents.TryGetValue(documentFilePath, out var older))
{
@ -275,7 +296,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(textLoader));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(projectFilePath, out var entry) &&
entry.State.Documents.TryGetValue(documentFilePath, out var older))
{
@ -313,7 +335,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(sourceText));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(projectFilePath, out var entry) &&
entry.State.Documents.TryGetValue(documentFilePath, out var older))
{
@ -366,7 +389,8 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(textLoader));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(projectFilePath, out var entry) &&
entry.State.Documents.TryGetValue(documentFilePath, out var older))
{
@ -392,7 +416,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(hostProject));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
// We don't expect to see a HostProject initialized multiple times for the same path. Just ignore it.
if (_projects.ContainsKey(hostProject.FilePath))
@ -415,7 +439,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(hostProject));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(hostProject.FilePath, out var entry))
{
@ -444,7 +468,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(projectWorkspaceState));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(projectFilePath, out var entry))
{
@ -468,7 +492,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(hostProject));
}
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
if (_projects.TryGetValue(hostProject.FilePath, out var entry))
{
@ -513,7 +537,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
// virtual so it can be overridden in tests
protected virtual void NotifyListeners(ProjectChangeEventArgs e)
{
_foregroundDispatcher.AssertForegroundThread();
_projectSnapshotManagerDispatcher.AssertDispatcherThread();
_notificationWork.Enqueue(e);
@ -536,7 +560,6 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
}
while (_notificationWork.Count > 0);
}
}
private class Entry

Просмотреть файл

@ -14,16 +14,16 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
internal class DefaultProjectSnapshotManagerFactory : ILanguageServiceFactory
{
private readonly IEnumerable<ProjectSnapshotChangeTrigger> _triggers;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
[ImportingConstructor]
public DefaultProjectSnapshotManagerFactory(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher,
[ImportMany] IEnumerable<ProjectSnapshotChangeTrigger> triggers)
{
if (foregroundDispatcher == null)
if (projectSnapshotManagerDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher));
}
if (triggers == null)
@ -31,7 +31,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
throw new ArgumentNullException(nameof(triggers));
}
_foregroundDispatcher = foregroundDispatcher;
_projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher;
_triggers = triggers;
}
@ -43,7 +43,7 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem
}
return new DefaultProjectSnapshotManager(
_foregroundDispatcher,
_projectSnapshotManagerDispatcher,
languageServices.WorkspaceServices.GetRequiredService<ErrorReporter>(),
_triggers,
languageServices.WorkspaceServices.Workspace);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше