mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -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",
|
||||
"request": "attach",
|
||||
"requireExactSource": false,
|
||||
"processId": 14720
|
||||
"processId": 17264
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -61,12 +61,27 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer
|
||||
|
||||
public class DidChangeTextDocumentParams : TextDocumentIdentifier
|
||||
{
|
||||
public TextDocumentUriChangeEvent TextDocument { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of changes to the document content.
|
||||
/// </summary>
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol
|
||||
#region Fields
|
||||
|
||||
private ChannelBase protocolChannel;
|
||||
// private AsyncQueue<Message> messagesToWrite;
|
||||
|
||||
private AsyncContextThread messageLoopThread;
|
||||
|
||||
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.
|
||||
//
|
||||
|
||||
using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
|
||||
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.
|
||||
//
|
||||
|
||||
using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
|
||||
|
||||
@@ -8,17 +8,23 @@ using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Channel;
|
||||
using Microsoft.SqlTools.EditorServices.Session;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.EditorServices.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.SqlTools.EditorServices.Protocol.Server
|
||||
{
|
||||
public class LanguageServer : LanguageServerBase
|
||||
{
|
||||
private EditorSession editorSession;
|
||||
|
||||
/// <param name="hostDetails">
|
||||
/// Provides details about the host application.
|
||||
/// </param>
|
||||
public LanguageServer(HostDetails hostDetails, ProfilePaths profilePaths)
|
||||
: base(new StdioServerChannel())
|
||||
{
|
||||
this.editorSession = new EditorSession();
|
||||
this.editorSession.StartSession(hostDetails, profilePaths);
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
@@ -43,6 +49,14 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.Server
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
DidChangeTextDocumentParams textChangeParams,
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,8 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
// using Microsoft.SqlTools.EditorServices.Console;
|
||||
// using Microsoft.SqlTools.EditorServices.Extensions;
|
||||
using System;
|
||||
using Microsoft.SqlTools.EditorServices.Session;
|
||||
// using Microsoft.SqlTools.EditorServices.Utility;
|
||||
// using System.IO;
|
||||
|
||||
namespace Microsoft.SqlTools.EditorServices
|
||||
{
|
||||
@@ -15,12 +12,8 @@ namespace Microsoft.SqlTools.EditorServices
|
||||
/// Manages a single session for all editor services. This
|
||||
/// includes managing all open script files for the session.
|
||||
/// </summary>
|
||||
public class EditorSession
|
||||
public class EditorSession : IDisposable
|
||||
{
|
||||
public void StartSession(HostDetails hostDetails, ProfilePaths profilePaths)
|
||||
{
|
||||
}
|
||||
#if false
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
@@ -33,6 +26,59 @@ namespace Microsoft.SqlTools.EditorServices
|
||||
/// </summary>
|
||||
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>
|
||||
/// Gets the LanguageService instance for this session.
|
||||
/// </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>
|
||||
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
|
||||
#region Private Fields
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
using Microsoft.SqlTools.EditorServices.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.SqlTools.EditorServices
|
||||
{
|
||||
@@ -18,8 +18,7 @@ namespace Microsoft.SqlTools.EditorServices
|
||||
/// </summary>
|
||||
public class Workspace
|
||||
{
|
||||
#if false
|
||||
#region Private Fields
|
||||
#region Private Fields
|
||||
|
||||
private Version SqlToolsVersion;
|
||||
private Dictionary<string, ScriptFile> workspaceFiles = new Dictionary<string, ScriptFile>();
|
||||
@@ -93,6 +92,70 @@ namespace Microsoft.SqlTools.EditorServices
|
||||
|
||||
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>
|
||||
/// Gets a new ScriptFile instance which is identified by the given file
|
||||
@@ -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)
|
||||
{
|
||||
if (IsPathInMemory(filePath))
|
||||
|
||||
Reference in New Issue
Block a user