mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
Clear and rebuild IntelliSense cache (#238)
* Stage changes to other machine * IntelliSense cache rebuild command * Move to other machine * Add a test for overwriting binding queue. * Move event handler into lanaguageservice.cs
This commit is contained in:
@@ -123,6 +123,28 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove the binding queue entry
|
||||||
|
/// </summary>
|
||||||
|
protected void RemoveBindingContext(string key)
|
||||||
|
{
|
||||||
|
lock (this.bindingContextLock)
|
||||||
|
{
|
||||||
|
if (this.BindingContextMap.ContainsKey(key))
|
||||||
|
{
|
||||||
|
// disconnect existing connection
|
||||||
|
var bindingContext = this.BindingContextMap[key];
|
||||||
|
if (bindingContext.ServerConnection != null && bindingContext.ServerConnection.IsOpen)
|
||||||
|
{
|
||||||
|
bindingContext.ServerConnection.Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove key from the map
|
||||||
|
this.BindingContextMap.Remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool HasPendingQueueItems
|
private bool HasPendingQueueItems
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@@ -51,8 +51,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use a ConnectionInfo item to create a connected binding context
|
/// Use a ConnectionInfo item to create a connected binding context
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connInfo"></param>
|
/// <param name="connInfo">Connection info used to create binding context</param>
|
||||||
public virtual string AddConnectionContext(ConnectionInfo connInfo)
|
/// <param name="overwrite">Overwrite existing context</param>
|
||||||
|
public virtual string AddConnectionContext(ConnectionInfo connInfo, bool overwrite = false)
|
||||||
{
|
{
|
||||||
if (connInfo == null)
|
if (connInfo == null)
|
||||||
{
|
{
|
||||||
@@ -63,8 +64,15 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
string connectionKey = GetConnectionContextKey(connInfo);
|
string connectionKey = GetConnectionContextKey(connInfo);
|
||||||
if (BindingContextExists(connectionKey))
|
if (BindingContextExists(connectionKey))
|
||||||
{
|
{
|
||||||
// no need to populate the context again since the context already exists
|
if (overwrite)
|
||||||
return connectionKey;
|
{
|
||||||
|
RemoveBindingContext(connectionKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no need to populate the context again since the context already exists
|
||||||
|
return connectionKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IBindingContext bindingContext = this.GetOrCreateBindingContext(connectionKey);
|
IBindingContext bindingContext = this.GetOrCreateBindingContext(connectionKey);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Parameters to be sent back with a rebuild IntelliSense event
|
||||||
|
/// </summary>
|
||||||
|
public class RebuildIntelliSenseParams
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// URI identifying the file that should have its IntelliSense cache rebuilt
|
||||||
|
/// </summary>
|
||||||
|
public string OwnerUri { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RebuildIntelliSenseNotification notification mapping entry
|
||||||
|
/// </summary>
|
||||||
|
public class RebuildIntelliSenseNotification
|
||||||
|
{
|
||||||
|
public static readonly
|
||||||
|
EventType<RebuildIntelliSenseParams> Type =
|
||||||
|
EventType<RebuildIntelliSenseParams>.Create("textDocument/rebuildIntelliSense");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -212,6 +212,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
serviceHost.SetRequestHandler(HoverRequest.Type, HandleHoverRequest);
|
serviceHost.SetRequestHandler(HoverRequest.Type, HandleHoverRequest);
|
||||||
serviceHost.SetRequestHandler(CompletionRequest.Type, HandleCompletionRequest);
|
serviceHost.SetRequestHandler(CompletionRequest.Type, HandleCompletionRequest);
|
||||||
serviceHost.SetRequestHandler(DefinitionRequest.Type, HandleDefinitionRequest);
|
serviceHost.SetRequestHandler(DefinitionRequest.Type, HandleDefinitionRequest);
|
||||||
|
serviceHost.SetEventHandler(RebuildIntelliSenseNotification.Type, HandleRebuildIntelliSenseNotification);
|
||||||
|
|
||||||
// Register a no-op shutdown task for validation of the shutdown logic
|
// Register a no-op shutdown task for validation of the shutdown logic
|
||||||
serviceHost.RegisterShutdownTask(async (shutdownParams, shutdownRequestContext) =>
|
serviceHost.RegisterShutdownTask(async (shutdownParams, shutdownRequestContext) =>
|
||||||
@@ -442,6 +443,62 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
await Task.FromResult(true);
|
await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the rebuild IntelliSense cache notification
|
||||||
|
/// </summary>
|
||||||
|
public async Task HandleRebuildIntelliSenseNotification(
|
||||||
|
RebuildIntelliSenseParams configChangeParams,
|
||||||
|
EventContext eventContext)
|
||||||
|
{
|
||||||
|
Logger.Write(LogLevel.Verbose, "HandleRebuildIntelliSenseNotification");
|
||||||
|
|
||||||
|
// Skip closing this file if the file doesn't exist
|
||||||
|
var scriptFile = this.CurrentWorkspace.GetFile(configChangeParams.OwnerUri);
|
||||||
|
if (scriptFile == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionInfo connInfo;
|
||||||
|
LanguageService.ConnectionServiceInstance.TryFindConnection(
|
||||||
|
scriptFile.ClientFilePath,
|
||||||
|
out connInfo);
|
||||||
|
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
ScriptParseInfo scriptInfo = GetScriptParseInfo(connInfo.OwnerUri, createIfNotExists: false);
|
||||||
|
if (scriptInfo != null && scriptInfo.IsConnected &&
|
||||||
|
Monitor.TryEnter(scriptInfo.BuildingMetadataLock, LanguageService.OnConnectionWaitTimeout))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.BindingQueue.AddConnectionContext(connInfo, overwrite: true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Write(LogLevel.Error, "Unknown error " + ex.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Set Metadata Build event to Signal state.
|
||||||
|
Monitor.Exit(scriptInfo.BuildingMetadataLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not in the preview window and diagnostics are enabled then run diagnostics
|
||||||
|
if (!IsPreviewWindow(scriptFile)
|
||||||
|
&& WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.IsDiagnositicsEnabled)
|
||||||
|
{
|
||||||
|
RunScriptDiagnostics(
|
||||||
|
new ScriptFile[] { scriptFile },
|
||||||
|
eventContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a notification to signal that autocomplete is ready
|
||||||
|
ServiceHost.Instance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = connInfo.OwnerUri});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle the file configuration change notification
|
/// Handle the file configuration change notification
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
/// List of callbacks to call when a text document is closed
|
/// List of callbacks to call when a text document is closed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<TextDocCloseCallback> TextDocCloseCallbacks { get; set; }
|
private List<TextDocCloseCallback> TextDocCloseCallbacks { get; set; }
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -189,7 +190,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
public void RegisterTextDocOpenCallback(TextDocOpenCallback task)
|
public void RegisterTextDocOpenCallback(TextDocOpenCallback task)
|
||||||
{
|
{
|
||||||
TextDocOpenCallbacks.Add(task);
|
TextDocOpenCallbacks.Add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -287,7 +288,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
var configUpdateTasks = ConfigChangeCallbacks.Select(
|
var configUpdateTasks = ConfigChangeCallbacks.Select(
|
||||||
t => t(configChangeParams.Settings, CurrentSettings, eventContext));
|
t => t(configChangeParams.Settings, CurrentSettings, eventContext));
|
||||||
await Task.WhenAll(configUpdateTasks);
|
await Task.WhenAll(configUpdateTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -135,5 +135,27 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
|
|||||||
SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, result.ScriptFile);
|
SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, result.ScriptFile);
|
||||||
Assert.NotNull(signatureHelp);
|
Assert.NotNull(signatureHelp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test overwriting the binding queue context
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public void OverwriteBindingContext()
|
||||||
|
{
|
||||||
|
var result = TestObjects.InitLiveConnectionInfo();
|
||||||
|
|
||||||
|
// add a new connection context
|
||||||
|
var connectionKey = LanguageService.Instance.BindingQueue.AddConnectionContext(result.ConnectionInfo, overwrite: true);
|
||||||
|
Assert.True(LanguageService.Instance.BindingQueue.BindingContextMap.ContainsKey(connectionKey));
|
||||||
|
|
||||||
|
// cache the server connection
|
||||||
|
var orgServerConnection = LanguageService.Instance.BindingQueue.BindingContextMap[connectionKey].ServerConnection;
|
||||||
|
Assert.NotNull(orgServerConnection);
|
||||||
|
|
||||||
|
// add a new connection context
|
||||||
|
connectionKey = LanguageService.Instance.BindingQueue.AddConnectionContext(result.ConnectionInfo, overwrite: true);
|
||||||
|
Assert.True(LanguageService.Instance.BindingQueue.BindingContextMap.ContainsKey(connectionKey));
|
||||||
|
Assert.False(object.ReferenceEquals(LanguageService.Instance.BindingQueue.BindingContextMap[connectionKey].ServerConnection, orgServerConnection));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
|
|||||||
|
|
||||||
// setup binding queue mock
|
// setup binding queue mock
|
||||||
bindingQueue = new Mock<ConnectedBindingQueue>();
|
bindingQueue = new Mock<ConnectedBindingQueue>();
|
||||||
bindingQueue.Setup(q => q.AddConnectionContext(It.IsAny<ConnectionInfo>()))
|
bindingQueue.Setup(q => q.AddConnectionContext(It.IsAny<ConnectionInfo>(), It.IsAny<bool>()))
|
||||||
.Returns(this.testConnectionKey);
|
.Returns(this.testConnectionKey);
|
||||||
|
|
||||||
// inject mock instances into the Language Service
|
// inject mock instances into the Language Service
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
|
|||||||
|
|
||||||
// setup binding queue mock
|
// setup binding queue mock
|
||||||
bindingQueue = new Mock<ConnectedBindingQueue>();
|
bindingQueue = new Mock<ConnectedBindingQueue>();
|
||||||
bindingQueue.Setup(q => q.AddConnectionContext(It.IsAny<ConnectionInfo>()))
|
bindingQueue.Setup(q => q.AddConnectionContext(It.IsAny<ConnectionInfo>(), It.IsAny<bool>()))
|
||||||
.Returns(this.testConnectionKey);
|
.Returns(this.testConnectionKey);
|
||||||
|
|
||||||
// inject mock instances into the Language Service
|
// inject mock instances into the Language Service
|
||||||
|
|||||||
Reference in New Issue
Block a user