mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-17 02:51:45 -05:00
LanguageService must send result or intellisense hangs (#395)
* LanguageService must send result or intellisense hangs - Unless the language services methods return results for requests, the VSCode language service protocol will never send a response up to its higher-level code. This means with intellisense off, it appears to hang instead of saying "No results found". This is clearly sub-optimal and if any other extension wants to provide SQL suggestions, it would break them from sending results - Minor refactor to fully remove Instance-field references in the code
This commit is contained in:
@@ -73,6 +73,8 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
|
|
||||||
private WorkspaceService<SqlToolsSettings> workspaceServiceInstance;
|
private WorkspaceService<SqlToolsSettings> workspaceServiceInstance;
|
||||||
|
|
||||||
|
private ServiceHost serviceHostInstance;
|
||||||
|
|
||||||
private object parseMapLock = new object();
|
private object parseMapLock = new object();
|
||||||
|
|
||||||
private ScriptParseInfo currentCompletionParseInfo;
|
private ScriptParseInfo currentCompletionParseInfo;
|
||||||
@@ -178,6 +180,22 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal ServiceHost ServiceHostInstance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.serviceHostInstance == null)
|
||||||
|
{
|
||||||
|
this.serviceHostInstance = ServiceHost.Instance;
|
||||||
|
}
|
||||||
|
return this.serviceHostInstance;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.serviceHostInstance = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current settings
|
/// Gets the current settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -233,6 +251,8 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
await Task.FromResult(0);
|
await Task.FromResult(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ServiceHostInstance = serviceHost;
|
||||||
|
|
||||||
// Register the configuration update handler
|
// Register the configuration update handler
|
||||||
WorkspaceServiceInstance.RegisterConfigChangeCallback(HandleDidChangeConfigurationNotification);
|
WorkspaceServiceInstance.RegisterConfigChangeCallback(HandleDidChangeConfigurationNotification);
|
||||||
|
|
||||||
@@ -270,7 +290,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
// check if Intellisense suggestions are enabled
|
// check if Intellisense suggestions are enabled
|
||||||
if (ShouldSkipIntellisense(textDocumentPosition.TextDocument.Uri))
|
if (ShouldSkipIntellisense(textDocumentPosition.TextDocument.Uri))
|
||||||
{
|
{
|
||||||
await Task.FromResult(true);
|
await requestContext.SendResult(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -283,7 +303,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
scriptFile.ClientFilePath,
|
scriptFile.ClientFilePath,
|
||||||
out connInfo);
|
out connInfo);
|
||||||
|
|
||||||
var completionItems = Instance.GetCompletionItems(
|
var completionItems = GetCompletionItems(
|
||||||
textDocumentPosition, scriptFile, connInfo);
|
textDocumentPosition, scriptFile, connInfo);
|
||||||
|
|
||||||
await requestContext.SendResult(completionItems);
|
await requestContext.SendResult(completionItems);
|
||||||
@@ -305,7 +325,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
// Note: Do not know file, so no need to check for MSSQL flavor
|
// Note: Do not know file, so no need to check for MSSQL flavor
|
||||||
if (!CurrentWorkspaceSettings.IsSuggestionsEnabled)
|
if (!CurrentWorkspaceSettings.IsSuggestionsEnabled)
|
||||||
{
|
{
|
||||||
await Task.FromResult(true);
|
await requestContext.SendResult(completionItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -369,14 +389,14 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
ReferencesParams referencesParams,
|
ReferencesParams referencesParams,
|
||||||
RequestContext<Location[]> requestContext)
|
RequestContext<Location[]> requestContext)
|
||||||
{
|
{
|
||||||
await Task.FromResult(true);
|
await requestContext.SendResult(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleDocumentHighlightRequest(
|
private async Task HandleDocumentHighlightRequest(
|
||||||
TextDocumentPosition textDocumentPosition,
|
TextDocumentPosition textDocumentPosition,
|
||||||
RequestContext<DocumentHighlight[]> requestContext)
|
RequestContext<DocumentHighlight[]> requestContext)
|
||||||
{
|
{
|
||||||
await Task.FromResult(true);
|
await requestContext.SendResult(null);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -387,7 +407,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
// check if Intellisense suggestions are enabled
|
// check if Intellisense suggestions are enabled
|
||||||
if (ShouldSkipNonMssqlFile(textDocumentPosition))
|
if (ShouldSkipNonMssqlFile(textDocumentPosition))
|
||||||
{
|
{
|
||||||
await Task.FromResult(true);
|
await requestContext.SendResult(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -528,19 +548,19 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send a notification to signal that autocomplete is ready
|
// Send a notification to signal that autocomplete is ready
|
||||||
ServiceHost.Instance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = connInfo.OwnerUri});
|
ServiceHostInstance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = connInfo.OwnerUri});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Send a notification to signal that autocomplete is ready
|
// Send a notification to signal that autocomplete is ready
|
||||||
await ServiceHost.Instance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = rebuildParams.OwnerUri});
|
await ServiceHostInstance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = rebuildParams.OwnerUri});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Write(LogLevel.Error, "Unknown error " + ex.ToString());
|
Logger.Write(LogLevel.Error, "Unknown error " + ex.ToString());
|
||||||
await ServiceHost.Instance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = rebuildParams.OwnerUri});
|
await ServiceHostInstance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = rebuildParams.OwnerUri});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,7 +741,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
PrepopulateCommonMetadata(info, scriptInfo, this.BindingQueue);
|
PrepopulateCommonMetadata(info, scriptInfo, this.BindingQueue);
|
||||||
|
|
||||||
// Send a notification to signal that autocomplete is ready
|
// Send a notification to signal that autocomplete is ready
|
||||||
ServiceHost.Instance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = info.OwnerUri});
|
ServiceHostInstance.SendEvent(IntelliSenseReadyNotification.Type, new IntelliSenseReadyParams() {OwnerUri = info.OwnerUri});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,27 +54,31 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.LanguageServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HandleSignatureHelpRequestNonMssqlFile()
|
public async Task HandleSignatureHelpRequestNonMssqlFile()
|
||||||
{
|
{
|
||||||
InitializeTestObjects();
|
InitializeTestObjects();
|
||||||
|
|
||||||
// setup the mock for SendResult
|
// setup the mock for SendResult
|
||||||
var signatureRequestContext = new Mock<RequestContext<SignatureHelp>>();
|
var signatureRequestContext = new Mock<RequestContext<SignatureHelp>>();
|
||||||
|
SignatureHelp result = null;
|
||||||
signatureRequestContext.Setup(rc => rc.SendResult(It.IsAny<SignatureHelp>()))
|
signatureRequestContext.Setup(rc => rc.SendResult(It.IsAny<SignatureHelp>()))
|
||||||
.Returns(Task.FromResult(0));
|
.Returns<SignatureHelp>((signature) => {
|
||||||
|
result = signature;
|
||||||
|
return Task.FromResult(0);
|
||||||
|
});
|
||||||
signatureRequestContext.Setup(rc => rc.SendError(It.IsAny<string>(), It.IsAny<int>())).Returns(Task.FromResult(0));
|
signatureRequestContext.Setup(rc => rc.SendError(It.IsAny<string>(), It.IsAny<int>())).Returns(Task.FromResult(0));
|
||||||
|
|
||||||
|
|
||||||
langService.CurrentWorkspaceSettings.SqlTools.IntelliSense.EnableIntellisense = true;
|
langService.CurrentWorkspaceSettings.SqlTools.IntelliSense.EnableIntellisense = true;
|
||||||
langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams {
|
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams {
|
||||||
Uri = textDocument.TextDocument.Uri,
|
Uri = textDocument.TextDocument.Uri,
|
||||||
Language = LanguageService.SQL_LANG.ToLower(),
|
Language = LanguageService.SQL_LANG.ToLower(),
|
||||||
Flavor = "NotMSSQL"
|
Flavor = "NotMSSQL"
|
||||||
}, null);
|
}, null);
|
||||||
Assert.NotNull(langService.HandleSignatureHelpRequest(textDocument, signatureRequestContext.Object));
|
await langService.HandleSignatureHelpRequest(textDocument, signatureRequestContext.Object);
|
||||||
|
// verify that the response was sent with a null response value
|
||||||
// verify that no events were sent
|
signatureRequestContext.Verify(m => m.SendResult(It.IsAny<SignatureHelp>()), Times.Once());
|
||||||
signatureRequestContext.Verify(m => m.SendResult(It.IsAny<SignatureHelp>()), Times.Never());
|
Assert.Null(result);
|
||||||
signatureRequestContext.Verify(m => m.SendError(It.IsAny<string>(), It.IsAny<int>()), Times.Never());
|
signatureRequestContext.Verify(m => m.SendError(It.IsAny<string>(), It.IsAny<int>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user