diff --git a/ServiceHost/.vscode/launch.json b/ServiceHost/.vscode/launch.json
index ea4209f7..18ebbb27 100644
--- a/ServiceHost/.vscode/launch.json
+++ b/ServiceHost/.vscode/launch.json
@@ -18,7 +18,7 @@
"type": "coreclr",
"request": "attach",
"requireExactSource": false,
- "processId": 14720
+ "processId": 17264
}
]
}
\ No newline at end of file
diff --git a/ServiceHost/LanguageServer/TextDocument.cs b/ServiceHost/LanguageServer/TextDocument.cs
index 9b477c96..9f477374 100644
--- a/ServiceHost/LanguageServer/TextDocument.cs
+++ b/ServiceHost/LanguageServer/TextDocument.cs
@@ -61,12 +61,27 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer
public class DidChangeTextDocumentParams : TextDocumentIdentifier
{
+ public TextDocumentUriChangeEvent TextDocument { get; set; }
+
///
/// Gets or sets the list of changes to the document content.
///
public TextDocumentChangeEvent[] ContentChanges { get; set; }
}
+ public class TextDocumentUriChangeEvent
+ {
+ ///
+ /// Gets or sets the Uri of the changed text document
+ ///
+ public string Uri { get; set; }
+
+ ///
+ /// Gets or sets the Version of the changed text document
+ ///
+ public int Version { get; set; }
+ }
+
public class TextDocumentChangeEvent
{
///
diff --git a/ServiceHost/MessageProtocol/MessageDispatcher.cs b/ServiceHost/MessageProtocol/MessageDispatcher.cs
index 7d2d9c4c..21c179e2 100644
--- a/ServiceHost/MessageProtocol/MessageDispatcher.cs
+++ b/ServiceHost/MessageProtocol/MessageDispatcher.cs
@@ -18,7 +18,7 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol
#region Fields
private ChannelBase protocolChannel;
- // private AsyncQueue messagesToWrite;
+
private AsyncContextThread messageLoopThread;
private Dictionary> requestHandlers =
diff --git a/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs b/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs
index edf14712..fa1d1518 100644
--- a/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs
+++ b/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs
@@ -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
{
diff --git a/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs b/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs
index 4088a223..941e249a 100644
--- a/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs
+++ b/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs
@@ -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;
diff --git a/ServiceHost/Server/LanguageServer.cs b/ServiceHost/Server/LanguageServer.cs
index 4f7367a4..2f0f7963 100644
--- a/ServiceHost/Server/LanguageServer.cs
+++ b/ServiceHost/Server/LanguageServer.cs
@@ -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;
+
///
/// Provides details about the host application.
///
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
});
}
+ ///
+ /// Handles text document change events
+ ///
+ ///
+ ///
+ ///
protected Task HandleDidChangeTextDocumentNotification(
DidChangeTextDocumentParams textChangeParams,
EventContext eventContext)
{
- Logger.Write(LogLevel.Normal, "HandleDidChangeTextDocumentNotification");
+ StringBuilder msg = new StringBuilder();
+ msg.Append("HandleDidChangeTextDocumentNotification");
+ List changedFiles = new List();
+
+ // 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);
}
diff --git a/ServiceHost/Session/EditorSession.cs b/ServiceHost/Session/EditorSession.cs
index 21c1b577..4b6c9a49 100644
--- a/ServiceHost/Session/EditorSession.cs
+++ b/ServiceHost/Session/EditorSession.cs
@@ -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.
///
- public class EditorSession
+ public class EditorSession : IDisposable
{
- public void StartSession(HostDetails hostDetails, ProfilePaths profilePaths)
- {
- }
-#if false
#region Properties
///
@@ -33,6 +26,59 @@ namespace Microsoft.SqlTools.EditorServices
///
public SqlToolsContext SqlToolsContext { get; private set; }
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Starts the session using the provided IConsoleHost implementation
+ /// for the ConsoleService.
+ ///
+ ///
+ /// Provides details about the host application.
+ ///
+ ///
+ /// An object containing the profile paths for the session.
+ ///
+ 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
+
+ ///
+ /// Disposes of any Runspaces that were created for the
+ /// services used in this session.
+ ///
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+
+#if false
+ #region Properties
+
+
+
+
+
///
/// Gets the LanguageService instance for this session.
///
diff --git a/ServiceHost/Session/SqlToolsContext.cs b/ServiceHost/Session/SqlToolsContext.cs
new file mode 100644
index 00000000..d8016afd
--- /dev/null
+++ b/ServiceHost/Session/SqlToolsContext.cs
@@ -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
+ {
+ ///
+ /// Gets the PowerShell version of the current runspace.
+ ///
+ public Version SqlToolsVersion
+ {
+ get; private set;
+ }
+
+ public SqlToolsContext(HostDetails hostDetails, ProfilePaths profilePaths)
+ {
+
+ }
+ }
+}
diff --git a/ServiceHost/Workspace/ScriptFile.cs b/ServiceHost/Workspace/ScriptFile.cs
index c68ecb96..7b041832 100644
--- a/ServiceHost/Workspace/ScriptFile.cs
+++ b/ServiceHost/Workspace/ScriptFile.cs
@@ -18,6 +18,30 @@ namespace Microsoft.SqlTools.EditorServices
///
public class ScriptFile
{
+ public ScriptFile(
+ string filePath,
+ string clientFilePath,
+ TextReader textReader,
+ Version SqlToolsVersion)
+ {
+ }
+
+ ///
+ /// Creates a new ScriptFile instance with the specified file contents.
+ ///
+ /// The path at which the script file resides.
+ /// The path which the client uses to identify the file.
+ /// The initial contents of the script file.
+ /// The version of SqlTools for which the script is being parsed.
+ public ScriptFile(
+ string filePath,
+ string clientFilePath,
+ string initialBuffer,
+ Version SqlToolsVersion)
+ {
+ }
+
+
#if false
#region Private Fields
diff --git a/ServiceHost/Workspace/Workspace.cs b/ServiceHost/Workspace/Workspace.cs
index b8635ef2..6188a806 100644
--- a/ServiceHost/Workspace/Workspace.cs
+++ b/ServiceHost/Workspace/Workspace.cs
@@ -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
///
public class Workspace
{
-#if false
- #region Private Fields
+ #region Private Fields
private Version SqlToolsVersion;
private Dictionary workspaceFiles = new Dictionary();
@@ -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");
+ }
+
+ ///
+ /// Unescapes any escaped [, ] or space characters. Typically use this before calling a
+ /// .NET API that doesn't understand PowerShell escaped chars.
+ ///
+ /// The path to unescape.
+ /// The path with the ` character before [, ] and spaces removed.
+ public static string UnescapePath(string path)
+ {
+ if (!path.Contains("`"))
+ {
+ return path;
+ }
+
+ return Regex.Replace(path, @"`(?=[ \[\]])", "");
+ }
+
+ #endregion
+
+#if false
+
+
+ #region Public Methods
+
///
/// 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))