mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 18:47:57 -05:00
Enable file change tracking with Workspace and EditorSession.
Also include misc. clean-ups related to removing unneeded PowerShell Language Service code.
This commit is contained in:
2
ServiceHost/.vscode/launch.json
vendored
2
ServiceHost/.vscode/launch.json
vendored
@@ -18,7 +18,7 @@
|
|||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"requireExactSource": false,
|
"requireExactSource": false,
|
||||||
"processId": 14720
|
"processId": 17264
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -61,12 +61,27 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer
|
|||||||
|
|
||||||
public class DidChangeTextDocumentParams : TextDocumentIdentifier
|
public class DidChangeTextDocumentParams : TextDocumentIdentifier
|
||||||
{
|
{
|
||||||
|
public TextDocumentUriChangeEvent TextDocument { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the list of changes to the document content.
|
/// Gets or sets the list of changes to the document content.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TextDocumentChangeEvent[] ContentChanges { get; set; }
|
public TextDocumentChangeEvent[] ContentChanges { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TextDocumentUriChangeEvent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Uri of the changed text document
|
||||||
|
/// </summary>
|
||||||
|
public string Uri { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Version of the changed text document
|
||||||
|
/// </summary>
|
||||||
|
public int Version { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class TextDocumentChangeEvent
|
public class TextDocumentChangeEvent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol
|
|||||||
#region Fields
|
#region Fields
|
||||||
|
|
||||||
private ChannelBase protocolChannel;
|
private ChannelBase protocolChannel;
|
||||||
// private AsyncQueue<Message> messagesToWrite;
|
|
||||||
private AsyncContextThread messageLoopThread;
|
private AsyncContextThread messageLoopThread;
|
||||||
|
|
||||||
private Dictionary<string, Func<Message, MessageWriter, Task>> requestHandlers =
|
private Dictionary<string, Func<Message, MessageWriter, Task>> requestHandlers =
|
||||||
|
|||||||
@@ -3,10 +3,7 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Serializers
|
namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Serializers
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|||||||
@@ -8,17 +8,23 @@ using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Channel;
|
|||||||
using Microsoft.SqlTools.EditorServices.Session;
|
using Microsoft.SqlTools.EditorServices.Session;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.EditorServices.Utility;
|
using Microsoft.SqlTools.EditorServices.Utility;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.EditorServices.Protocol.Server
|
namespace Microsoft.SqlTools.EditorServices.Protocol.Server
|
||||||
{
|
{
|
||||||
public class LanguageServer : LanguageServerBase
|
public class LanguageServer : LanguageServerBase
|
||||||
{
|
{
|
||||||
|
private EditorSession editorSession;
|
||||||
|
|
||||||
/// <param name="hostDetails">
|
/// <param name="hostDetails">
|
||||||
/// Provides details about the host application.
|
/// Provides details about the host application.
|
||||||
/// </param>
|
/// </param>
|
||||||
public LanguageServer(HostDetails hostDetails, ProfilePaths profilePaths)
|
public LanguageServer(HostDetails hostDetails, ProfilePaths profilePaths)
|
||||||
: base(new StdioServerChannel())
|
: base(new StdioServerChannel())
|
||||||
{
|
{
|
||||||
|
this.editorSession = new EditorSession();
|
||||||
|
this.editorSession.StartSession(hostDetails, profilePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
@@ -43,6 +49,14 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.Server
|
|||||||
|
|
||||||
protected override async Task Shutdown()
|
protected override async Task Shutdown()
|
||||||
{
|
{
|
||||||
|
Logger.Write(LogLevel.Normal, "Language service is shutting down...");
|
||||||
|
|
||||||
|
if (this.editorSession != null)
|
||||||
|
{
|
||||||
|
this.editorSession.Dispose();
|
||||||
|
this.editorSession = null;
|
||||||
|
}
|
||||||
|
|
||||||
await Task.FromResult(true);
|
await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +94,46 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.Server
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles text document change events
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="textChangeParams"></param>
|
||||||
|
/// <param name="eventContext"></param>
|
||||||
|
/// <returns></returns>
|
||||||
protected Task HandleDidChangeTextDocumentNotification(
|
protected Task HandleDidChangeTextDocumentNotification(
|
||||||
DidChangeTextDocumentParams textChangeParams,
|
DidChangeTextDocumentParams textChangeParams,
|
||||||
EventContext eventContext)
|
EventContext eventContext)
|
||||||
{
|
{
|
||||||
Logger.Write(LogLevel.Normal, "HandleDidChangeTextDocumentNotification");
|
StringBuilder msg = new StringBuilder();
|
||||||
|
msg.Append("HandleDidChangeTextDocumentNotification");
|
||||||
|
List<ScriptFile> changedFiles = new List<ScriptFile>();
|
||||||
|
|
||||||
|
// A text change notification can batch multiple change requests
|
||||||
|
foreach (var textChange in textChangeParams.ContentChanges)
|
||||||
|
{
|
||||||
|
string fileUri = textChangeParams.TextDocument.Uri;
|
||||||
|
msg.AppendLine();
|
||||||
|
msg.Append(" File: ");
|
||||||
|
msg.Append(fileUri);
|
||||||
|
|
||||||
|
ScriptFile changedFile = editorSession.Workspace.GetFile(fileUri);
|
||||||
|
|
||||||
|
// changedFile.ApplyChange(
|
||||||
|
// GetFileChangeDetails(
|
||||||
|
// textChange.Range.Value,
|
||||||
|
// textChange.Text));
|
||||||
|
|
||||||
|
// changedFiles.Add(changedFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Write(LogLevel.Normal, msg.ToString());
|
||||||
|
|
||||||
|
// // TODO: Get all recently edited files in the workspace
|
||||||
|
// this.RunScriptDiagnostics(
|
||||||
|
// changedFiles.ToArray(),
|
||||||
|
// editorSession,
|
||||||
|
// eventContext);
|
||||||
|
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,8 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
// using Microsoft.SqlTools.EditorServices.Console;
|
using System;
|
||||||
// using Microsoft.SqlTools.EditorServices.Extensions;
|
|
||||||
using Microsoft.SqlTools.EditorServices.Session;
|
using Microsoft.SqlTools.EditorServices.Session;
|
||||||
// using Microsoft.SqlTools.EditorServices.Utility;
|
|
||||||
// using System.IO;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.EditorServices
|
namespace Microsoft.SqlTools.EditorServices
|
||||||
{
|
{
|
||||||
@@ -15,12 +12,8 @@ namespace Microsoft.SqlTools.EditorServices
|
|||||||
/// Manages a single session for all editor services. This
|
/// Manages a single session for all editor services. This
|
||||||
/// includes managing all open script files for the session.
|
/// includes managing all open script files for the session.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EditorSession
|
public class EditorSession : IDisposable
|
||||||
{
|
{
|
||||||
public void StartSession(HostDetails hostDetails, ProfilePaths profilePaths)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#if false
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -33,6 +26,59 @@ namespace Microsoft.SqlTools.EditorServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public SqlToolsContext SqlToolsContext { get; private set; }
|
public SqlToolsContext SqlToolsContext { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the session using the provided IConsoleHost implementation
|
||||||
|
/// for the ConsoleService.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hostDetails">
|
||||||
|
/// Provides details about the host application.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="profilePaths">
|
||||||
|
/// An object containing the profile paths for the session.
|
||||||
|
/// </param>
|
||||||
|
public void StartSession(HostDetails hostDetails, ProfilePaths profilePaths)
|
||||||
|
{
|
||||||
|
// Initialize all services
|
||||||
|
this.SqlToolsContext = new SqlToolsContext(hostDetails, profilePaths);
|
||||||
|
|
||||||
|
|
||||||
|
// this.LanguageService = new LanguageService(this.SqlToolsContext);
|
||||||
|
// this.DebugService = new DebugService(this.SqlToolsContext);
|
||||||
|
// this.ConsoleService = new ConsoleService(this.SqlToolsContext);
|
||||||
|
// this.ExtensionService = new ExtensionService(this.SqlToolsContext);
|
||||||
|
|
||||||
|
// this.InstantiateAnalysisService();
|
||||||
|
|
||||||
|
// Create a workspace to contain open files
|
||||||
|
this.Workspace = new Workspace(this.SqlToolsContext.SqlToolsVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes of any Runspaces that were created for the
|
||||||
|
/// services used in this session.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#if false
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the LanguageService instance for this session.
|
/// Gets the LanguageService instance for this session.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
25
ServiceHost/Session/SqlToolsContext.cs
Normal file
25
ServiceHost/Session/SqlToolsContext.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.EditorServices.Session
|
||||||
|
{
|
||||||
|
public class SqlToolsContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PowerShell version of the current runspace.
|
||||||
|
/// </summary>
|
||||||
|
public Version SqlToolsVersion
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SqlToolsContext(HostDetails hostDetails, ProfilePaths profilePaths)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,30 @@ namespace Microsoft.SqlTools.EditorServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ScriptFile
|
public class ScriptFile
|
||||||
{
|
{
|
||||||
|
public ScriptFile(
|
||||||
|
string filePath,
|
||||||
|
string clientFilePath,
|
||||||
|
TextReader textReader,
|
||||||
|
Version SqlToolsVersion)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new ScriptFile instance with the specified file contents.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">The path at which the script file resides.</param>
|
||||||
|
/// <param name="clientFilePath">The path which the client uses to identify the file.</param>
|
||||||
|
/// <param name="initialBuffer">The initial contents of the script file.</param>
|
||||||
|
/// <param name="SqlToolsVersion">The version of SqlTools for which the script is being parsed.</param>
|
||||||
|
public ScriptFile(
|
||||||
|
string filePath,
|
||||||
|
string clientFilePath,
|
||||||
|
string initialBuffer,
|
||||||
|
Version SqlToolsVersion)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if false
|
#if false
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
using Microsoft.SqlTools.EditorServices.Utility;
|
using Microsoft.SqlTools.EditorServices.Utility;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.EditorServices
|
namespace Microsoft.SqlTools.EditorServices
|
||||||
{
|
{
|
||||||
@@ -18,7 +18,6 @@ namespace Microsoft.SqlTools.EditorServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Workspace
|
public class Workspace
|
||||||
{
|
{
|
||||||
#if false
|
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private Version SqlToolsVersion;
|
private Version SqlToolsVersion;
|
||||||
@@ -94,6 +93,70 @@ namespace Microsoft.SqlTools.EditorServices
|
|||||||
return scriptFile;
|
return scriptFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string ResolveFilePath(string filePath)
|
||||||
|
{
|
||||||
|
if (!IsPathInMemory(filePath))
|
||||||
|
{
|
||||||
|
if (filePath.StartsWith(@"file://"))
|
||||||
|
{
|
||||||
|
// Client sent the path in URI format, extract the local path and trim
|
||||||
|
// any extraneous slashes
|
||||||
|
Uri fileUri = new Uri(filePath);
|
||||||
|
filePath = fileUri.LocalPath.TrimStart('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some clients send paths with UNIX-style slashes, replace those if necessary
|
||||||
|
filePath = filePath.Replace('/', '\\');
|
||||||
|
|
||||||
|
// Clients could specify paths with escaped space, [ and ] characters which .NET APIs
|
||||||
|
// will not handle. These paths will get appropriately escaped just before being passed
|
||||||
|
// into the SqlTools engine.
|
||||||
|
filePath = UnescapePath(filePath);
|
||||||
|
|
||||||
|
// Get the absolute file path
|
||||||
|
filePath = Path.GetFullPath(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Write(LogLevel.Verbose, "Resolved path: " + filePath);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool IsPathInMemory(string filePath)
|
||||||
|
{
|
||||||
|
// When viewing SqlTools files in the Git diff viewer, VS Code
|
||||||
|
// sends the contents of the file at HEAD with a URI that starts
|
||||||
|
// with 'inmemory'. Untitled files which have been marked of
|
||||||
|
// type SqlTools have a path starting with 'untitled'.
|
||||||
|
return
|
||||||
|
filePath.StartsWith("inmemory") ||
|
||||||
|
filePath.StartsWith("untitled");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unescapes any escaped [, ] or space characters. Typically use this before calling a
|
||||||
|
/// .NET API that doesn't understand PowerShell escaped chars.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path to unescape.</param>
|
||||||
|
/// <returns>The path with the ` character before [, ] and spaces removed.</returns>
|
||||||
|
public static string UnescapePath(string path)
|
||||||
|
{
|
||||||
|
if (!path.Contains("`"))
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Regex.Replace(path, @"`(?=[ \[\]])", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#if false
|
||||||
|
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a new ScriptFile instance which is identified by the given file
|
/// Gets a new ScriptFile instance which is identified by the given file
|
||||||
/// path and initially contains the given buffer contents.
|
/// path and initially contains the given buffer contents.
|
||||||
@@ -222,46 +285,6 @@ namespace Microsoft.SqlTools.EditorServices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ResolveFilePath(string filePath)
|
|
||||||
{
|
|
||||||
if (!IsPathInMemory(filePath))
|
|
||||||
{
|
|
||||||
if (filePath.StartsWith(@"file://"))
|
|
||||||
{
|
|
||||||
// Client sent the path in URI format, extract the local path and trim
|
|
||||||
// any extraneous slashes
|
|
||||||
Uri fileUri = new Uri(filePath);
|
|
||||||
filePath = fileUri.LocalPath.TrimStart('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some clients send paths with UNIX-style slashes, replace those if necessary
|
|
||||||
filePath = filePath.Replace('/', '\\');
|
|
||||||
|
|
||||||
// Clients could specify paths with escaped space, [ and ] characters which .NET APIs
|
|
||||||
// will not handle. These paths will get appropriately escaped just before being passed
|
|
||||||
// into the SqlTools engine.
|
|
||||||
filePath = SqlToolsContext.UnescapePath(filePath);
|
|
||||||
|
|
||||||
// Get the absolute file path
|
|
||||||
filePath = Path.GetFullPath(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Write(LogLevel.Verbose, "Resolved path: " + filePath);
|
|
||||||
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static bool IsPathInMemory(string filePath)
|
|
||||||
{
|
|
||||||
// When viewing SqlTools files in the Git diff viewer, VS Code
|
|
||||||
// sends the contents of the file at HEAD with a URI that starts
|
|
||||||
// with 'inmemory'. Untitled files which have been marked of
|
|
||||||
// type SqlTools have a path starting with 'untitled'.
|
|
||||||
return
|
|
||||||
filePath.StartsWith("inmemory") ||
|
|
||||||
filePath.StartsWith("untitled");
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetBaseFilePath(string filePath)
|
private string GetBaseFilePath(string filePath)
|
||||||
{
|
{
|
||||||
if (IsPathInMemory(filePath))
|
if (IsPathInMemory(filePath))
|
||||||
|
|||||||
Reference in New Issue
Block a user