From ae54004e999f7caeb425925012da03fcde53a897 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Sun, 17 Jul 2016 11:44:03 -0700 Subject: [PATCH] Actually stage the deletes. Update .gitignore --- .gitignore | 273 ++++++++- ServiceHost/.vscode/launch.json | 24 - ServiceHost/.vscode/tasks.json | 14 - .../LanguageServer/ClientCapabilities.cs | 18 - ServiceHost/LanguageServer/Completion.cs | 85 --- ServiceHost/LanguageServer/Configuration.cs | 21 - ServiceHost/LanguageServer/Definition.cs | 17 - ServiceHost/LanguageServer/Diagnostics.cs | 71 --- .../LanguageServer/DocumentHighlight.cs | 31 - .../LanguageServer/ExpandAliasRequest.cs | 16 - .../LanguageServer/FindModuleRequest.cs | 24 - ServiceHost/LanguageServer/Hover.cs | 32 -- ServiceHost/LanguageServer/Initialize.cs | 46 -- .../LanguageServer/InstallModuleRequest.cs | 16 - ServiceHost/LanguageServer/References.cs | 27 - .../LanguageServer/ServerCapabilities.cs | 63 -- .../LanguageServer/ShowOnlineHelpRequest.cs | 16 - ServiceHost/LanguageServer/Shutdown.cs | 32 -- ServiceHost/LanguageServer/SignatureHelp.cs | 42 -- ServiceHost/LanguageServer/TextDocument.cs | 164 ------ .../LanguageServer/WorkspaceSymbols.cs | 62 -- .../LanguageSupport/LanguageService.cs | 57 -- .../MessageProtocol/Channel/ChannelBase.cs | 81 --- .../Channel/StdioClientChannel.cs | 125 ---- .../Channel/StdioServerChannel.cs | 60 -- ServiceHost/MessageProtocol/Constants.cs | 25 - ServiceHost/MessageProtocol/EventContext.cs | 33 -- ServiceHost/MessageProtocol/EventType.cs | 33 -- ServiceHost/MessageProtocol/IMessageSender.cs | 22 - .../MessageProtocol/IMessageSerializer.cs | 30 - ServiceHost/MessageProtocol/Message.cs | 136 ----- .../MessageProtocol/MessageDispatcher.cs | 325 ----------- .../MessageProtocol/MessageParseException.cs | 23 - .../MessageProtocol/MessageProtocolType.cs | 23 - ServiceHost/MessageProtocol/MessageReader.cs | 262 --------- ServiceHost/MessageProtocol/MessageWriter.cs | 140 ----- .../MessageProtocol/ProtocolEndpoint.cs | 313 ---------- ServiceHost/MessageProtocol/RequestContext.cs | 47 -- ServiceHost/MessageProtocol/RequestType.cs | 24 - .../Serializers/JsonRpcMessageSerializer.cs | 99 ---- .../Serializers/V8MessageSerializer.cs | 113 ---- ServiceHost/Program.cs | 40 -- ServiceHost/Properties/AssemblyInfo.cs | 44 -- ServiceHost/Server/LanguageServer.cs | 517 ----------------- ServiceHost/Server/LanguageServerBase.cs | 84 --- .../Server/LanguageServerEditorOperations.cs | 114 ---- ServiceHost/Server/LanguageServerSettings.cs | 90 --- ServiceHost/Session/EditorSession.cs | 75 --- ServiceHost/Session/HostDetails.cs | 92 --- ServiceHost/Session/OutputType.cs | 41 -- ServiceHost/Session/OutputWrittenEventArgs.cs | 65 --- ServiceHost/Session/ProfilePaths.cs | 109 ---- ServiceHost/Session/SqlToolsContext.cs | 25 - ServiceHost/Utility/AsyncContext.cs | 52 -- ServiceHost/Utility/AsyncContextThread.cs | 85 --- ServiceHost/Utility/AsyncLock.cs | 103 ---- ServiceHost/Utility/AsyncQueue.cs | 155 ----- ServiceHost/Utility/Extensions.cs | 34 -- ServiceHost/Utility/Logger.cs | 222 -------- .../Utility/ThreadSynchronizationContext.cs | 77 --- ServiceHost/Utility/Validate.cs | 143 ----- ServiceHost/Workspace/BufferPosition.cs | 110 ---- ServiceHost/Workspace/BufferRange.cs | 123 ---- ServiceHost/Workspace/FileChange.cs | 38 -- ServiceHost/Workspace/FilePosition.cs | 110 ---- ServiceHost/Workspace/ScriptFile.cs | 538 ------------------ ServiceHost/Workspace/ScriptFileMarker.cs | 56 -- ServiceHost/Workspace/ScriptRegion.cs | 89 --- ServiceHost/Workspace/Workspace.cs | 248 -------- ServiceHost/project.json | 21 - 70 files changed, 270 insertions(+), 6295 deletions(-) delete mode 100644 ServiceHost/.vscode/launch.json delete mode 100644 ServiceHost/.vscode/tasks.json delete mode 100644 ServiceHost/LanguageServer/ClientCapabilities.cs delete mode 100644 ServiceHost/LanguageServer/Completion.cs delete mode 100644 ServiceHost/LanguageServer/Configuration.cs delete mode 100644 ServiceHost/LanguageServer/Definition.cs delete mode 100644 ServiceHost/LanguageServer/Diagnostics.cs delete mode 100644 ServiceHost/LanguageServer/DocumentHighlight.cs delete mode 100644 ServiceHost/LanguageServer/ExpandAliasRequest.cs delete mode 100644 ServiceHost/LanguageServer/FindModuleRequest.cs delete mode 100644 ServiceHost/LanguageServer/Hover.cs delete mode 100644 ServiceHost/LanguageServer/Initialize.cs delete mode 100644 ServiceHost/LanguageServer/InstallModuleRequest.cs delete mode 100644 ServiceHost/LanguageServer/References.cs delete mode 100644 ServiceHost/LanguageServer/ServerCapabilities.cs delete mode 100644 ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs delete mode 100644 ServiceHost/LanguageServer/Shutdown.cs delete mode 100644 ServiceHost/LanguageServer/SignatureHelp.cs delete mode 100644 ServiceHost/LanguageServer/TextDocument.cs delete mode 100644 ServiceHost/LanguageServer/WorkspaceSymbols.cs delete mode 100644 ServiceHost/LanguageSupport/LanguageService.cs delete mode 100644 ServiceHost/MessageProtocol/Channel/ChannelBase.cs delete mode 100644 ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs delete mode 100644 ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs delete mode 100644 ServiceHost/MessageProtocol/Constants.cs delete mode 100644 ServiceHost/MessageProtocol/EventContext.cs delete mode 100644 ServiceHost/MessageProtocol/EventType.cs delete mode 100644 ServiceHost/MessageProtocol/IMessageSender.cs delete mode 100644 ServiceHost/MessageProtocol/IMessageSerializer.cs delete mode 100644 ServiceHost/MessageProtocol/Message.cs delete mode 100644 ServiceHost/MessageProtocol/MessageDispatcher.cs delete mode 100644 ServiceHost/MessageProtocol/MessageParseException.cs delete mode 100644 ServiceHost/MessageProtocol/MessageProtocolType.cs delete mode 100644 ServiceHost/MessageProtocol/MessageReader.cs delete mode 100644 ServiceHost/MessageProtocol/MessageWriter.cs delete mode 100644 ServiceHost/MessageProtocol/ProtocolEndpoint.cs delete mode 100644 ServiceHost/MessageProtocol/RequestContext.cs delete mode 100644 ServiceHost/MessageProtocol/RequestType.cs delete mode 100644 ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs delete mode 100644 ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs delete mode 100644 ServiceHost/Program.cs delete mode 100644 ServiceHost/Properties/AssemblyInfo.cs delete mode 100644 ServiceHost/Server/LanguageServer.cs delete mode 100644 ServiceHost/Server/LanguageServerBase.cs delete mode 100644 ServiceHost/Server/LanguageServerEditorOperations.cs delete mode 100644 ServiceHost/Server/LanguageServerSettings.cs delete mode 100644 ServiceHost/Session/EditorSession.cs delete mode 100644 ServiceHost/Session/HostDetails.cs delete mode 100644 ServiceHost/Session/OutputType.cs delete mode 100644 ServiceHost/Session/OutputWrittenEventArgs.cs delete mode 100644 ServiceHost/Session/ProfilePaths.cs delete mode 100644 ServiceHost/Session/SqlToolsContext.cs delete mode 100644 ServiceHost/Utility/AsyncContext.cs delete mode 100644 ServiceHost/Utility/AsyncContextThread.cs delete mode 100644 ServiceHost/Utility/AsyncLock.cs delete mode 100644 ServiceHost/Utility/AsyncQueue.cs delete mode 100644 ServiceHost/Utility/Extensions.cs delete mode 100644 ServiceHost/Utility/Logger.cs delete mode 100644 ServiceHost/Utility/ThreadSynchronizationContext.cs delete mode 100644 ServiceHost/Utility/Validate.cs delete mode 100644 ServiceHost/Workspace/BufferPosition.cs delete mode 100644 ServiceHost/Workspace/BufferRange.cs delete mode 100644 ServiceHost/Workspace/FileChange.cs delete mode 100644 ServiceHost/Workspace/FilePosition.cs delete mode 100644 ServiceHost/Workspace/ScriptFile.cs delete mode 100644 ServiceHost/Workspace/ScriptFileMarker.cs delete mode 100644 ServiceHost/Workspace/ScriptRegion.cs delete mode 100644 ServiceHost/Workspace/Workspace.cs delete mode 100644 ServiceHost/project.json diff --git a/.gitignore b/.gitignore index d1fcfc4e..4c997e2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,270 @@ -bin -obj -project.lock.json \ No newline at end of file +syntax: glob + +### VisualStudio ### + +# Project.json lock file +project.lock.json + +# Tool Runtime Dir +/[Tt]ools/ + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +msbuild.log +msbuild.err +msbuild.wrn + + + +# Cross building rootfs +cross/rootfs/ + +# Visual Studio 2015 +.vs/ + +# Visual Studio 2015 Pre-CTP6 +*.sln.ide +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +*.pubxml +*.publishproj + +# NuGet Packages +*.nuget.props +*.nuget.targets +*.nupkg +**/packages/* + +# NuGet package restore lockfiles +project.lock.json + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +*.metaproj +*.metaproj.tmp + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +### MonoDevelop ### + +*.pidb +*.userprefs + +### Windows ### + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Linux ### + +*~ + +# KDE directory preferences +.directory + +### OSX ### + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# vim temporary files +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist +*~ + +# Visual Studio Code +.vscode/ diff --git a/ServiceHost/.vscode/launch.json b/ServiceHost/.vscode/launch.json deleted file mode 100644 index 18ebbb27..00000000 --- a/ServiceHost/.vscode/launch.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": ".NET Core Launch (console)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceRoot}/bin/Debug/netcoreapp1.0/servicehost.dll", - "args": [], - "cwd": "${workspaceRoot}", - "externalConsole": true, - "requireExactSource": false, - "stopAtEntry": false - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach", - "requireExactSource": false, - "processId": 17264 - } - ] -} \ No newline at end of file diff --git a/ServiceHost/.vscode/tasks.json b/ServiceHost/.vscode/tasks.json deleted file mode 100644 index 67d6eb75..00000000 --- a/ServiceHost/.vscode/tasks.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": "0.1.0", - "command": "dotnet", - "isShellCommand": true, - "args": [], - "tasks": [ - { - "taskName": "build", - "args": [], - "isBuildCommand": true, - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/ServiceHost/LanguageServer/ClientCapabilities.cs b/ServiceHost/LanguageServer/ClientCapabilities.cs deleted file mode 100644 index 70e2d068..00000000 --- a/ServiceHost/LanguageServer/ClientCapabilities.cs +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - /// - /// Defines a class that describes the capabilities of a language - /// client. At this time no specific capabilities are listed for - /// clients. - /// - public class ClientCapabilities - { - } -} - diff --git a/ServiceHost/LanguageServer/Completion.cs b/ServiceHost/LanguageServer/Completion.cs deleted file mode 100644 index 5f26ea96..00000000 --- a/ServiceHost/LanguageServer/Completion.cs +++ /dev/null @@ -1,85 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class CompletionRequest - { - public static readonly - RequestType Type = - RequestType.Create("textDocument/completion"); - } - - public class CompletionResolveRequest - { - public static readonly - RequestType Type = - RequestType.Create("completionItem/resolve"); - } - - public enum CompletionItemKind - { - Text = 1, - Method = 2, - Function = 3, - Constructor = 4, - Field = 5, - Variable = 6, - Class = 7, - Interface = 8, - Module = 9, - Property = 10, - Unit = 11, - Value = 12, - Enum = 13, - Keyword = 14, - Snippet = 15, - Color = 16, - File = 17, - Reference = 18 - } - - [DebuggerDisplay("NewText = {NewText}, Range = {Range.Start.Line}:{Range.Start.Character} - {Range.End.Line}:{Range.End.Character}")] - public class TextEdit - { - public Range Range { get; set; } - - public string NewText { get; set; } - } - - [DebuggerDisplay("Kind = {Kind.ToString()}, Label = {Label}, Detail = {Detail}")] - public class CompletionItem - { - public string Label { get; set; } - - public CompletionItemKind? Kind { get; set; } - - public string Detail { get; set; } - - /// - /// Gets or sets the documentation string for the completion item. - /// - public string Documentation { get; set; } - - public string SortText { get; set; } - - public string FilterText { get; set; } - - public string InsertText { get; set; } - - public TextEdit TextEdit { get; set; } - - /// - /// Gets or sets a custom data field that allows the server to mark - /// each completion item with an identifier that will help correlate - /// the item to the previous completion request during a completion - /// resolve request. - /// - public object Data { get; set; } - } -} diff --git a/ServiceHost/LanguageServer/Configuration.cs b/ServiceHost/LanguageServer/Configuration.cs deleted file mode 100644 index b9ad87db..00000000 --- a/ServiceHost/LanguageServer/Configuration.cs +++ /dev/null @@ -1,21 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class DidChangeConfigurationNotification - { - public static readonly - EventType> Type = - EventType>.Create("workspace/didChangeConfiguration"); - } - - public class DidChangeConfigurationParams - { - public TConfig Settings { get; set; } - } -} diff --git a/ServiceHost/LanguageServer/Definition.cs b/ServiceHost/LanguageServer/Definition.cs deleted file mode 100644 index b18845c3..00000000 --- a/ServiceHost/LanguageServer/Definition.cs +++ /dev/null @@ -1,17 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class DefinitionRequest - { - public static readonly - RequestType Type = - RequestType.Create("textDocument/definition"); - } -} - diff --git a/ServiceHost/LanguageServer/Diagnostics.cs b/ServiceHost/LanguageServer/Diagnostics.cs deleted file mode 100644 index a5472607..00000000 --- a/ServiceHost/LanguageServer/Diagnostics.cs +++ /dev/null @@ -1,71 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class PublishDiagnosticsNotification - { - public static readonly - EventType Type = - EventType.Create("textDocument/publishDiagnostics"); - - /// - /// Gets or sets the URI for which diagnostic information is reported. - /// - public string Uri { get; set; } - - /// - /// Gets or sets the array of diagnostic information items. - /// - public Diagnostic[] Diagnostics { get; set; } - } - - public enum DiagnosticSeverity - { - /// - /// Indicates that the diagnostic represents an error. - /// - Error = 1, - - /// - /// Indicates that the diagnostic represents a warning. - /// - Warning = 2, - - /// - /// Indicates that the diagnostic represents an informational message. - /// - Information = 3, - - /// - /// Indicates that the diagnostic represents a hint. - /// - Hint = 4 - } - - public class Diagnostic - { - public Range Range { get; set; } - - /// - /// Gets or sets the severity of the diagnostic. If omitted, the - /// client should interpret the severity. - /// - public DiagnosticSeverity? Severity { get; set; } - - /// - /// Gets or sets the diagnostic's code (optional). - /// - public string Code { get; set; } - - /// - /// Gets or sets the diagnostic message. - /// - public string Message { get; set; } - } -} - diff --git a/ServiceHost/LanguageServer/DocumentHighlight.cs b/ServiceHost/LanguageServer/DocumentHighlight.cs deleted file mode 100644 index 6849ddfb..00000000 --- a/ServiceHost/LanguageServer/DocumentHighlight.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public enum DocumentHighlightKind - { - Text = 1, - Read = 2, - Write = 3 - } - - public class DocumentHighlight - { - public Range Range { get; set; } - - public DocumentHighlightKind Kind { get; set; } - } - - public class DocumentHighlightRequest - { - public static readonly - RequestType Type = - RequestType.Create("textDocument/documentHighlight"); - } -} - diff --git a/ServiceHost/LanguageServer/ExpandAliasRequest.cs b/ServiceHost/LanguageServer/ExpandAliasRequest.cs deleted file mode 100644 index d7f9fde4..00000000 --- a/ServiceHost/LanguageServer/ExpandAliasRequest.cs +++ /dev/null @@ -1,16 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class ExpandAliasRequest - { - public static readonly - RequestType Type = - RequestType.Create("SqlTools/expandAlias"); - } -} diff --git a/ServiceHost/LanguageServer/FindModuleRequest.cs b/ServiceHost/LanguageServer/FindModuleRequest.cs deleted file mode 100644 index ab78a158..00000000 --- a/ServiceHost/LanguageServer/FindModuleRequest.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; -using System.Collections.Generic; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class FindModuleRequest - { - public static readonly - RequestType, object> Type = - RequestType, object>.Create("SqlTools/findModule"); - } - - - public class PSModuleMessage - { - public string Name { get; set; } - public string Description { get; set; } - } -} diff --git a/ServiceHost/LanguageServer/Hover.cs b/ServiceHost/LanguageServer/Hover.cs deleted file mode 100644 index 2e196fba..00000000 --- a/ServiceHost/LanguageServer/Hover.cs +++ /dev/null @@ -1,32 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class MarkedString - { - public string Language { get; set; } - - public string Value { get; set; } - } - - public class Hover - { - public MarkedString[] Contents { get; set; } - - public Range? Range { get; set; } - } - - public class HoverRequest - { - public static readonly - RequestType Type = - RequestType.Create("textDocument/hover"); - - } -} - diff --git a/ServiceHost/LanguageServer/Initialize.cs b/ServiceHost/LanguageServer/Initialize.cs deleted file mode 100644 index 7551835e..00000000 --- a/ServiceHost/LanguageServer/Initialize.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class InitializeRequest - { - public static readonly - RequestType Type = - RequestType.Create("initialize"); - - /// - /// Gets or sets the root path of the editor's open workspace. - /// If null it is assumed that a file was opened without having - /// a workspace open. - /// - public string RootPath { get; set; } - - /// - /// Gets or sets the capabilities provided by the client (editor). - /// - public ClientCapabilities Capabilities { get; set; } - } - - public class InitializeResult - { - /// - /// Gets or sets the capabilities provided by the language server. - /// - public ServerCapabilities Capabilities { get; set; } - } - - public class InitializeError - { - /// - /// Gets or sets a boolean indicating whether the client should retry - /// sending the Initialize request after showing the error to the user. - /// - public bool Retry { get; set;} - } -} - diff --git a/ServiceHost/LanguageServer/InstallModuleRequest.cs b/ServiceHost/LanguageServer/InstallModuleRequest.cs deleted file mode 100644 index b03b8864..00000000 --- a/ServiceHost/LanguageServer/InstallModuleRequest.cs +++ /dev/null @@ -1,16 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - class InstallModuleRequest - { - public static readonly - RequestType Type = - RequestType.Create("SqlTools/installModule"); - } -} diff --git a/ServiceHost/LanguageServer/References.cs b/ServiceHost/LanguageServer/References.cs deleted file mode 100644 index 25a92b12..00000000 --- a/ServiceHost/LanguageServer/References.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class ReferencesRequest - { - public static readonly - RequestType Type = - RequestType.Create("textDocument/references"); - } - - public class ReferencesParams : TextDocumentPosition - { - public ReferencesContext Context { get; set; } - } - - public class ReferencesContext - { - public bool IncludeDeclaration { get; set; } - } -} - diff --git a/ServiceHost/LanguageServer/ServerCapabilities.cs b/ServiceHost/LanguageServer/ServerCapabilities.cs deleted file mode 100644 index 2f7404d9..00000000 --- a/ServiceHost/LanguageServer/ServerCapabilities.cs +++ /dev/null @@ -1,63 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class ServerCapabilities - { - public TextDocumentSyncKind? TextDocumentSync { get; set; } - - public bool? HoverProvider { get; set; } - - public CompletionOptions CompletionProvider { get; set; } - - public SignatureHelpOptions SignatureHelpProvider { get; set; } - - public bool? DefinitionProvider { get; set; } - - public bool? ReferencesProvider { get; set; } - - public bool? DocumentHighlightProvider { get; set; } - - public bool? DocumentSymbolProvider { get; set; } - - public bool? WorkspaceSymbolProvider { get; set; } - } - - /// - /// Defines the document synchronization strategies that a server may support. - /// - public enum TextDocumentSyncKind - { - /// - /// Indicates that documents should not be synced at all. - /// - None = 0, - - /// - /// Indicates that document changes are always sent with the full content. - /// - Full, - - /// - /// Indicates that document changes are sent as incremental changes after - /// the initial document content has been sent. - /// - Incremental - } - - public class CompletionOptions - { - public bool? ResolveProvider { get; set; } - - public string[] TriggerCharacters { get; set; } - } - - public class SignatureHelpOptions - { - public string[] TriggerCharacters { get; set; } - } -} - diff --git a/ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs b/ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs deleted file mode 100644 index 8f21fb1b..00000000 --- a/ServiceHost/LanguageServer/ShowOnlineHelpRequest.cs +++ /dev/null @@ -1,16 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class ShowOnlineHelpRequest - { - public static readonly - RequestType Type = - RequestType.Create("SqlTools/showOnlineHelp"); - } -} diff --git a/ServiceHost/LanguageServer/Shutdown.cs b/ServiceHost/LanguageServer/Shutdown.cs deleted file mode 100644 index f0a7bbd2..00000000 --- a/ServiceHost/LanguageServer/Shutdown.cs +++ /dev/null @@ -1,32 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - /// - /// Defines a message that is sent from the client to request - /// that the server shut down. - /// - public class ShutdownRequest - { - public static readonly - RequestType Type = - RequestType.Create("shutdown"); - } - - /// - /// Defines an event that is sent from the client to notify that - /// the client is exiting and the server should as well. - /// - public class ExitNotification - { - public static readonly - EventType Type = - EventType.Create("exit"); - } -} - diff --git a/ServiceHost/LanguageServer/SignatureHelp.cs b/ServiceHost/LanguageServer/SignatureHelp.cs deleted file mode 100644 index 5d4233e3..00000000 --- a/ServiceHost/LanguageServer/SignatureHelp.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public class SignatureHelpRequest - { - public static readonly - RequestType Type = - RequestType.Create("textDocument/signatureHelp"); - } - - public class ParameterInformation - { - public string Label { get; set; } - - public string Documentation { get; set; } - } - - public class SignatureInformation - { - public string Label { get; set; } - - public string Documentation { get; set; } - - public ParameterInformation[] Parameters { get; set; } - } - - public class SignatureHelp - { - public SignatureInformation[] Signatures { get; set; } - - public int? ActiveSignature { get; set; } - - public int? ActiveParameter { get; set; } - } -} - diff --git a/ServiceHost/LanguageServer/TextDocument.cs b/ServiceHost/LanguageServer/TextDocument.cs deleted file mode 100644 index 9f477374..00000000 --- a/ServiceHost/LanguageServer/TextDocument.cs +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - /// - /// Defines a base parameter class for identifying a text document. - /// - [DebuggerDisplay("TextDocumentIdentifier = {Uri}")] - public class TextDocumentIdentifier - { - /// - /// Gets or sets the URI which identifies the path of the - /// text document. - /// - public string Uri { get; set; } - } - - /// - /// Defines a position in a text document. - /// - [DebuggerDisplay("TextDocumentPosition = {Position.Line}:{Position.Character}")] - public class TextDocumentPosition : TextDocumentIdentifier - { - /// - /// Gets or sets the position in the document. - /// - public Position Position { get; set; } - } - - public class DidOpenTextDocumentNotification : TextDocumentIdentifier - { - public static readonly - EventType Type = - EventType.Create("textDocument/didOpen"); - - /// - /// Gets or sets the full content of the opened document. - /// - public string Text { get; set; } - } - - public class DidCloseTextDocumentNotification - { - public static readonly - EventType Type = - EventType.Create("textDocument/didClose"); - } - - public class DidChangeTextDocumentNotification - { - public static readonly - EventType Type = - EventType.Create("textDocument/didChange"); - } - - 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 - { - /// - /// Gets or sets the Range where the document was changed. Will - /// be null if the server's TextDocumentSyncKind is Full. - /// - public Range? Range { get; set; } - - /// - /// Gets or sets the length of the Range being replaced in the - /// document. Will be null if the server's TextDocumentSyncKind is - /// Full. - /// - public int? RangeLength { get; set; } - - /// - /// Gets or sets the new text of the document. - /// - public string Text { get; set; } - } - - [DebuggerDisplay("Position = {Line}:{Character}")] - public class Position - { - /// - /// Gets or sets the zero-based line number. - /// - public int Line { get; set; } - - /// - /// Gets or sets the zero-based column number. - /// - public int Character { get; set; } - } - - [DebuggerDisplay("Start = {Start.Line}:{Start.Character}, End = {End.Line}:{End.Character}")] - public struct Range - { - /// - /// Gets or sets the starting position of the range. - /// - public Position Start { get; set; } - - /// - /// Gets or sets the ending position of the range. - /// - public Position End { get; set; } - } - - [DebuggerDisplay("Range = {Range.Start.Line}:{Range.Start.Character} - {Range.End.Line}:{Range.End.Character}, Uri = {Uri}")] - public class Location - { - /// - /// Gets or sets the URI indicating the file in which the location refers. - /// - public string Uri { get; set; } - - /// - /// Gets or sets the Range indicating the range in which location refers. - /// - public Range Range { get; set; } - } - - public enum FileChangeType - { - Created = 1, - - Changed, - - Deleted - } - - public class FileEvent - { - public string Uri { get; set; } - - public FileChangeType Type { get; set; } - } -} - diff --git a/ServiceHost/LanguageServer/WorkspaceSymbols.cs b/ServiceHost/LanguageServer/WorkspaceSymbols.cs deleted file mode 100644 index 25a554b5..00000000 --- a/ServiceHost/LanguageServer/WorkspaceSymbols.cs +++ /dev/null @@ -1,62 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol; - -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer -{ - public enum SymbolKind - { - File = 1, - Module = 2, - Namespace = 3, - Package = 4, - Class = 5, - Method = 6, - Property = 7, - Field = 8, - Constructor = 9, - Enum = 10, - Interface = 11, - Function = 12, - Variable = 13, - Constant = 14, - String = 15, - Number = 16, - Boolean = 17, - Array = 18, - } - - public class SymbolInformation - { - public string Name { get; set; } - - public SymbolKind Kind { get; set; } - - public Location Location { get; set; } - - public string ContainerName { get; set;} - } - - public class DocumentSymbolRequest - { - public static readonly - RequestType Type = - RequestType.Create("textDocument/documentSymbol"); - } - - public class WorkspaceSymbolRequest - { - public static readonly - RequestType Type = - RequestType.Create("workspace/symbol"); - } - - public class WorkspaceSymbolParams - { - public string Query { get; set;} - } -} - diff --git a/ServiceHost/LanguageSupport/LanguageService.cs b/ServiceHost/LanguageSupport/LanguageService.cs deleted file mode 100644 index 3ab77697..00000000 --- a/ServiceHost/LanguageSupport/LanguageService.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// 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.EditorServices; -using Microsoft.SqlTools.EditorServices.Session; - -namespace Microsoft.SqlTools.LanguageSupport -{ - /// - /// Main class for Language Service functionality - /// - public class LanguageService - { - /// - /// Gets or sets the current SQL Tools context - /// - /// - private SqlToolsContext Context { get; set; } - - /// - /// Constructor for the Language Service class - /// - /// - public LanguageService(SqlToolsContext context) - { - this.Context = context; - } - - /// - /// Gets a list of semantic diagnostic marks for the provided script file - /// - /// - public ScriptFileMarker[] GetSemanticMarkers(ScriptFile scriptFile) - { - // the commented out snippet is an example of how to create a error marker - // semanticMarkers = new ScriptFileMarker[1]; - // semanticMarkers[0] = new ScriptFileMarker() - // { - // Message = "Error message", - // Level = ScriptFileMarkerLevel.Error, - // ScriptRegion = new ScriptRegion() - // { - // File = scriptFile.FilePath, - // StartLineNumber = 2, - // StartColumnNumber = 2, - // StartOffset = 0, - // EndLineNumber = 4, - // EndColumnNumber = 10, - // EndOffset = 0 - // } - // }; - return new ScriptFileMarker[0]; - } - } -} diff --git a/ServiceHost/MessageProtocol/Channel/ChannelBase.cs b/ServiceHost/MessageProtocol/Channel/ChannelBase.cs deleted file mode 100644 index 848da39f..00000000 --- a/ServiceHost/MessageProtocol/Channel/ChannelBase.cs +++ /dev/null @@ -1,81 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol.Serializers; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Channel -{ - /// - /// Defines a base implementation for servers and their clients over a - /// single kind of communication channel. - /// - public abstract class ChannelBase - { - /// - /// Gets a boolean that is true if the channel is connected or false if not. - /// - public bool IsConnected { get; protected set; } - - /// - /// Gets the MessageReader for reading messages from the channel. - /// - public MessageReader MessageReader { get; protected set; } - - /// - /// Gets the MessageWriter for writing messages to the channel. - /// - public MessageWriter MessageWriter { get; protected set; } - - /// - /// Starts the channel and initializes the MessageDispatcher. - /// - /// The type of message protocol used by the channel. - public void Start(MessageProtocolType messageProtocolType) - { - IMessageSerializer messageSerializer = null; - if (messageProtocolType == MessageProtocolType.LanguageServer) - { - messageSerializer = new JsonRpcMessageSerializer(); - } - else - { - messageSerializer = new V8MessageSerializer(); - } - - this.Initialize(messageSerializer); - } - - /// - /// Returns a Task that allows the consumer of the ChannelBase - /// implementation to wait until a connection has been made to - /// the opposite endpoint whether it's a client or server. - /// - /// A Task to be awaited until a connection is made. - public abstract Task WaitForConnection(); - - /// - /// Stops the channel. - /// - public void Stop() - { - this.Shutdown(); - } - - /// - /// A method to be implemented by subclasses to handle the - /// actual initialization of the channel and the creation and - /// assignment of the MessageReader and MessageWriter properties. - /// - /// The IMessageSerializer to use for message serialization. - protected abstract void Initialize(IMessageSerializer messageSerializer); - - /// - /// A method to be implemented by subclasses to handle shutdown - /// of the channel once Stop is called. - /// - protected abstract void Shutdown(); - } -} diff --git a/ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs b/ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs deleted file mode 100644 index 5390f52d..00000000 --- a/ServiceHost/MessageProtocol/Channel/StdioClientChannel.cs +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Channel -{ - /// - /// Provides a client implementation for the standard I/O channel. - /// Launches the server process and then attaches to its console - /// streams. - /// - public class StdioClientChannel : ChannelBase - { - private string serviceProcessPath; - private string serviceProcessArguments; - - private Stream inputStream; - private Stream outputStream; - private Process serviceProcess; - - /// - /// Gets the process ID of the server process. - /// - public int ProcessId { get; private set; } - - /// - /// Initializes an instance of the StdioClient. - /// - /// The full path to the server process executable. - /// Optional arguments to pass to the service process executable. - public StdioClientChannel( - string serverProcessPath, - params string[] serverProcessArguments) - { - this.serviceProcessPath = serverProcessPath; - - if (serverProcessArguments != null) - { - this.serviceProcessArguments = - string.Join( - " ", - serverProcessArguments); - } - } - - protected override void Initialize(IMessageSerializer messageSerializer) - { - this.serviceProcess = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = this.serviceProcessPath, - Arguments = this.serviceProcessArguments, - CreateNoWindow = true, - UseShellExecute = false, - RedirectStandardInput = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - StandardOutputEncoding = Encoding.UTF8, - }, - EnableRaisingEvents = true, - }; - - // Start the process - this.serviceProcess.Start(); - this.ProcessId = this.serviceProcess.Id; - - // Open the standard input/output streams - this.inputStream = this.serviceProcess.StandardOutput.BaseStream; - this.outputStream = this.serviceProcess.StandardInput.BaseStream; - - // Set up the message reader and writer - this.MessageReader = - new MessageReader( - this.inputStream, - messageSerializer); - - this.MessageWriter = - new MessageWriter( - this.outputStream, - messageSerializer); - - this.IsConnected = true; - } - - public override Task WaitForConnection() - { - // We're always connected immediately in the stdio channel - return Task.FromResult(true); - } - - protected override void Shutdown() - { - if (this.inputStream != null) - { - this.inputStream.Dispose(); - this.inputStream = null; - } - - if (this.outputStream != null) - { - this.outputStream.Dispose(); - this.outputStream = null; - } - - if (this.MessageReader != null) - { - this.MessageReader = null; - } - - if (this.MessageWriter != null) - { - this.MessageWriter = null; - } - - this.serviceProcess.Kill(); - } - } -} diff --git a/ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs b/ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs deleted file mode 100644 index 0b9376d4..00000000 --- a/ServiceHost/MessageProtocol/Channel/StdioServerChannel.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Channel -{ - /// - /// Provides a server implementation for the standard I/O channel. - /// When started in a process, attaches to the console I/O streams - /// to communicate with the client that launched the process. - /// - public class StdioServerChannel : ChannelBase - { - private Stream inputStream; - private Stream outputStream; - - protected override void Initialize(IMessageSerializer messageSerializer) - { -#if !NanoServer - // Ensure that the console is using UTF-8 encoding - System.Console.InputEncoding = Encoding.UTF8; - System.Console.OutputEncoding = Encoding.UTF8; -#endif - - // Open the standard input/output streams - this.inputStream = System.Console.OpenStandardInput(); - this.outputStream = System.Console.OpenStandardOutput(); - - // Set up the reader and writer - this.MessageReader = - new MessageReader( - this.inputStream, - messageSerializer); - - this.MessageWriter = - new MessageWriter( - this.outputStream, - messageSerializer); - - this.IsConnected = true; - } - - public override Task WaitForConnection() - { - // We're always connected immediately in the stdio channel - return Task.FromResult(true); - } - - protected override void Shutdown() - { - // No default implementation needed, streams will be - // disposed on process shutdown. - } - } -} diff --git a/ServiceHost/MessageProtocol/Constants.cs b/ServiceHost/MessageProtocol/Constants.cs deleted file mode 100644 index 0fae5d8d..00000000 --- a/ServiceHost/MessageProtocol/Constants.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - public static class Constants - { - public const string ContentLengthFormatString = "Content-Length: {0}\r\n\r\n"; - public static readonly JsonSerializerSettings JsonSerializerSettings; - - static Constants() - { - JsonSerializerSettings = new JsonSerializerSettings(); - - // Camel case all object properties - JsonSerializerSettings.ContractResolver = - new CamelCasePropertyNamesContractResolver(); - } - } -} diff --git a/ServiceHost/MessageProtocol/EventContext.cs b/ServiceHost/MessageProtocol/EventContext.cs deleted file mode 100644 index eb42ebbb..00000000 --- a/ServiceHost/MessageProtocol/EventContext.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - /// - /// Provides context for a received event so that handlers - /// can write events back to the channel. - /// - public class EventContext - { - private MessageWriter messageWriter; - - public EventContext(MessageWriter messageWriter) - { - this.messageWriter = messageWriter; - } - - public async Task SendEvent( - EventType eventType, - TParams eventParams) - { - await this.messageWriter.WriteEvent( - eventType, - eventParams); - } - } -} - diff --git a/ServiceHost/MessageProtocol/EventType.cs b/ServiceHost/MessageProtocol/EventType.cs deleted file mode 100644 index dd460817..00000000 --- a/ServiceHost/MessageProtocol/EventType.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - /// - /// Defines an event type with a particular method name. - /// - /// The parameter type for this event. - public class EventType - { - /// - /// Gets the method name for the event type. - /// - public string MethodName { get; private set; } - - /// - /// Creates an EventType instance with the given parameter type and method name. - /// - /// The method name of the event. - /// A new EventType instance for the defined type. - public static EventType Create(string methodName) - { - return new EventType() - { - MethodName = methodName - }; - } - } -} - diff --git a/ServiceHost/MessageProtocol/IMessageSender.cs b/ServiceHost/MessageProtocol/IMessageSender.cs deleted file mode 100644 index 7f331eed..00000000 --- a/ServiceHost/MessageProtocol/IMessageSender.cs +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - internal interface IMessageSender - { - Task SendEvent( - EventType eventType, - TParams eventParams); - - Task SendRequest( - RequestType requestType, - TParams requestParams, - bool waitForResponse); - } -} - diff --git a/ServiceHost/MessageProtocol/IMessageSerializer.cs b/ServiceHost/MessageProtocol/IMessageSerializer.cs deleted file mode 100644 index 81b23fa6..00000000 --- a/ServiceHost/MessageProtocol/IMessageSerializer.cs +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using Newtonsoft.Json.Linq; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - /// - /// Defines a common interface for message serializers. - /// - public interface IMessageSerializer - { - /// - /// Serializes a Message to a JObject. - /// - /// The message to be serialized. - /// A JObject which contains the JSON representation of the message. - JObject SerializeMessage(Message message); - - /// - /// Deserializes a JObject to a Messsage. - /// - /// The JObject containing the JSON representation of the message. - /// The Message that was represented by the JObject. - Message DeserializeMessage(JObject messageJson); - } -} - diff --git a/ServiceHost/MessageProtocol/Message.cs b/ServiceHost/MessageProtocol/Message.cs deleted file mode 100644 index 75dab5cd..00000000 --- a/ServiceHost/MessageProtocol/Message.cs +++ /dev/null @@ -1,136 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics; -using Newtonsoft.Json.Linq; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - /// - /// Defines all possible message types. - /// - public enum MessageType - { - Unknown, - Request, - Response, - Event - } - - /// - /// Provides common details for protocol messages of any format. - /// - [DebuggerDisplay("MessageType = {MessageType.ToString()}, Method = {Method}, Id = {Id}")] - public class Message - { - /// - /// Gets or sets the message type. - /// - public MessageType MessageType { get; set; } - - /// - /// Gets or sets the message's sequence ID. - /// - public string Id { get; set; } - - /// - /// Gets or sets the message's method/command name. - /// - public string Method { get; set; } - - /// - /// Gets or sets a JToken containing the contents of the message. - /// - public JToken Contents { get; set; } - - /// - /// Gets or sets a JToken containing error details. - /// - public JToken Error { get; set; } - - /// - /// Creates a message with an Unknown type. - /// - /// A message with Unknown type. - public static Message Unknown() - { - return new Message - { - MessageType = MessageType.Unknown - }; - } - - /// - /// Creates a message with a Request type. - /// - /// The sequence ID of the request. - /// The method name of the request. - /// The contents of the request. - /// A message with a Request type. - public static Message Request(string id, string method, JToken contents) - { - return new Message - { - MessageType = MessageType.Request, - Id = id, - Method = method, - Contents = contents - }; - } - - /// - /// Creates a message with a Response type. - /// - /// The sequence ID of the original request. - /// The method name of the original request. - /// The contents of the response. - /// A message with a Response type. - public static Message Response(string id, string method, JToken contents) - { - return new Message - { - MessageType = MessageType.Response, - Id = id, - Method = method, - Contents = contents - }; - } - - /// - /// Creates a message with a Response type and error details. - /// - /// The sequence ID of the original request. - /// The method name of the original request. - /// The error details of the response. - /// A message with a Response type and error details. - public static Message ResponseError(string id, string method, JToken error) - { - return new Message - { - MessageType = MessageType.Response, - Id = id, - Method = method, - Error = error - }; - } - - /// - /// Creates a message with an Event type. - /// - /// The method name of the event. - /// The contents of the event. - /// A message with an Event type. - public static Message Event(string method, JToken contents) - { - return new Message - { - MessageType = MessageType.Event, - Method = method, - Contents = contents - }; - } - } -} - diff --git a/ServiceHost/MessageProtocol/MessageDispatcher.cs b/ServiceHost/MessageProtocol/MessageDispatcher.cs deleted file mode 100644 index 21c179e2..00000000 --- a/ServiceHost/MessageProtocol/MessageDispatcher.cs +++ /dev/null @@ -1,325 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol.Channel; -using Microsoft.SqlTools.EditorServices.Utility; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - public class MessageDispatcher - { - #region Fields - - private ChannelBase protocolChannel; - - private AsyncContextThread messageLoopThread; - - private Dictionary> requestHandlers = - new Dictionary>(); - - private Dictionary> eventHandlers = - new Dictionary>(); - - private Action responseHandler; - - private CancellationTokenSource messageLoopCancellationToken = - new CancellationTokenSource(); - - #endregion - - #region Properties - - public SynchronizationContext SynchronizationContext { get; private set; } - - public bool InMessageLoopThread - { - get - { - // We're in the same thread as the message loop if the - // current synchronization context equals the one we - // know. - return SynchronizationContext.Current == this.SynchronizationContext; - } - } - - protected MessageReader MessageReader { get; private set; } - - protected MessageWriter MessageWriter { get; private set; } - - - #endregion - - #region Constructors - - public MessageDispatcher(ChannelBase protocolChannel) - { - this.protocolChannel = protocolChannel; - this.MessageReader = protocolChannel.MessageReader; - this.MessageWriter = protocolChannel.MessageWriter; - } - - #endregion - - #region Public Methods - - public void Start() - { - // Start the main message loop thread. The Task is - // not explicitly awaited because it is running on - // an independent background thread. - this.messageLoopThread = new AsyncContextThread("Message Dispatcher"); - this.messageLoopThread - .Run(() => this.ListenForMessages(this.messageLoopCancellationToken.Token)) - .ContinueWith(this.OnListenTaskCompleted); - } - - public void Stop() - { - // Stop the message loop thread - if (this.messageLoopThread != null) - { - this.messageLoopCancellationToken.Cancel(); - this.messageLoopThread.Stop(); - } - } - - public void SetRequestHandler( - RequestType requestType, - Func, Task> requestHandler) - { - this.SetRequestHandler( - requestType, - requestHandler, - false); - } - - public void SetRequestHandler( - RequestType requestType, - Func, Task> requestHandler, - bool overrideExisting) - { - if (overrideExisting) - { - // Remove the existing handler so a new one can be set - this.requestHandlers.Remove(requestType.MethodName); - } - - this.requestHandlers.Add( - requestType.MethodName, - (requestMessage, messageWriter) => - { - var requestContext = - new RequestContext( - requestMessage, - messageWriter); - - TParams typedParams = default(TParams); - if (requestMessage.Contents != null) - { - // TODO: Catch parse errors! - typedParams = requestMessage.Contents.ToObject(); - } - - return requestHandler(typedParams, requestContext); - }); - } - - public void SetEventHandler( - EventType eventType, - Func eventHandler) - { - this.SetEventHandler( - eventType, - eventHandler, - false); - } - - public void SetEventHandler( - EventType eventType, - Func eventHandler, - bool overrideExisting) - { - if (overrideExisting) - { - // Remove the existing handler so a new one can be set - this.eventHandlers.Remove(eventType.MethodName); - } - - this.eventHandlers.Add( - eventType.MethodName, - (eventMessage, messageWriter) => - { - var eventContext = new EventContext(messageWriter); - - TParams typedParams = default(TParams); - if (eventMessage.Contents != null) - { - // TODO: Catch parse errors! - typedParams = eventMessage.Contents.ToObject(); - } - - return eventHandler(typedParams, eventContext); - }); - } - - public void SetResponseHandler(Action responseHandler) - { - this.responseHandler = responseHandler; - } - - #endregion - - #region Events - - public event EventHandler UnhandledException; - - protected void OnUnhandledException(Exception unhandledException) - { - if (this.UnhandledException != null) - { - this.UnhandledException(this, unhandledException); - } - } - - #endregion - - #region Private Methods - - private async Task ListenForMessages(CancellationToken cancellationToken) - { - this.SynchronizationContext = SynchronizationContext.Current; - - // Run the message loop - bool isRunning = true; - while (isRunning && !cancellationToken.IsCancellationRequested) - { - Message newMessage = null; - - try - { - // Read a message from the channel - newMessage = await this.MessageReader.ReadMessage(); - } - catch (MessageParseException e) - { - // TODO: Write an error response - - Logger.Write( - LogLevel.Error, - "Could not parse a message that was received:\r\n\r\n" + - e.ToString()); - - // Continue the loop - continue; - } - catch (EndOfStreamException) - { - // The stream has ended, end the message loop - break; - } - catch (Exception e) - { - var b = e.Message; - newMessage = null; - } - - // The message could be null if there was an error parsing the - // previous message. In this case, do not try to dispatch it. - if (newMessage != null) - { - // Process the message - await this.DispatchMessage( - newMessage, - this.MessageWriter); - } - } - } - - protected async Task DispatchMessage( - Message messageToDispatch, - MessageWriter messageWriter) - { - Task handlerToAwait = null; - - if (messageToDispatch.MessageType == MessageType.Request) - { - Func requestHandler = null; - if (this.requestHandlers.TryGetValue(messageToDispatch.Method, out requestHandler)) - { - handlerToAwait = requestHandler(messageToDispatch, messageWriter); - } - else - { - // TODO: Message not supported error - } - } - else if (messageToDispatch.MessageType == MessageType.Response) - { - if (this.responseHandler != null) - { - this.responseHandler(messageToDispatch); - } - } - else if (messageToDispatch.MessageType == MessageType.Event) - { - Func eventHandler = null; - if (this.eventHandlers.TryGetValue(messageToDispatch.Method, out eventHandler)) - { - handlerToAwait = eventHandler(messageToDispatch, messageWriter); - } - else - { - // TODO: Message not supported error - } - } - else - { - // TODO: Return message not supported - } - - if (handlerToAwait != null) - { - try - { - await handlerToAwait; - } - catch (TaskCanceledException) - { - // Some tasks may be cancelled due to legitimate - // timeouts so don't let those exceptions go higher. - } - catch (AggregateException e) - { - if (!(e.InnerExceptions[0] is TaskCanceledException)) - { - // Cancelled tasks aren't a problem, so rethrow - // anything that isn't a TaskCanceledException - throw e; - } - } - } - } - - private void OnListenTaskCompleted(Task listenTask) - { - if (listenTask.IsFaulted) - { - this.OnUnhandledException(listenTask.Exception); - } - else if (listenTask.IsCompleted || listenTask.IsCanceled) - { - // TODO: Dispose of anything? - } - } - - #endregion - } -} - diff --git a/ServiceHost/MessageProtocol/MessageParseException.cs b/ServiceHost/MessageProtocol/MessageParseException.cs deleted file mode 100644 index 98a17c20..00000000 --- a/ServiceHost/MessageProtocol/MessageParseException.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// 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.Protocol.MessageProtocol -{ - public class MessageParseException : Exception - { - public string OriginalMessageText { get; private set; } - - public MessageParseException( - string originalMessageText, - string errorMessage, - params object[] errorMessageArgs) - : base(string.Format(errorMessage, errorMessageArgs)) - { - this.OriginalMessageText = originalMessageText; - } - } -} diff --git a/ServiceHost/MessageProtocol/MessageProtocolType.cs b/ServiceHost/MessageProtocol/MessageProtocolType.cs deleted file mode 100644 index 5484ae3c..00000000 --- a/ServiceHost/MessageProtocol/MessageProtocolType.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - /// - /// Defines the possible message protocol types. - /// - public enum MessageProtocolType - { - /// - /// Identifies the language server message protocol. - /// - LanguageServer, - - /// - /// Identifies the debug adapter message protocol. - /// - DebugAdapter - } -} diff --git a/ServiceHost/MessageProtocol/MessageReader.cs b/ServiceHost/MessageProtocol/MessageReader.cs deleted file mode 100644 index a2df43ba..00000000 --- a/ServiceHost/MessageProtocol/MessageReader.cs +++ /dev/null @@ -1,262 +0,0 @@ -// -// 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.EditorServices.Utility; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - public class MessageReader - { - #region Private Fields - - public const int DefaultBufferSize = 8192; - public const double BufferResizeTrigger = 0.25; - - private const int CR = 0x0D; - private const int LF = 0x0A; - private static string[] NewLineDelimiters = new string[] { Environment.NewLine }; - - private Stream inputStream; - private IMessageSerializer messageSerializer; - private Encoding messageEncoding; - - private ReadState readState; - private bool needsMoreData = true; - private int readOffset; - private int bufferEndOffset; - private byte[] messageBuffer = new byte[DefaultBufferSize]; - - private int expectedContentLength; - private Dictionary messageHeaders; - - enum ReadState - { - Headers, - Content - } - - #endregion - - #region Constructors - - public MessageReader( - Stream inputStream, - IMessageSerializer messageSerializer, - Encoding messageEncoding = null) - { - Validate.IsNotNull("streamReader", inputStream); - Validate.IsNotNull("messageSerializer", messageSerializer); - - this.inputStream = inputStream; - this.messageSerializer = messageSerializer; - - this.messageEncoding = messageEncoding; - if (messageEncoding == null) - { - this.messageEncoding = Encoding.UTF8; - } - - this.messageBuffer = new byte[DefaultBufferSize]; - } - - #endregion - - #region Public Methods - - public async Task ReadMessage() - { - string messageContent = null; - - // Do we need to read more data or can we process the existing buffer? - while (!this.needsMoreData || await this.ReadNextChunk()) - { - // Clear the flag since we should have what we need now - this.needsMoreData = false; - - // Do we need to look for message headers? - if (this.readState == ReadState.Headers && - !this.TryReadMessageHeaders()) - { - // If we don't have enough data to read headers yet, keep reading - this.needsMoreData = true; - continue; - } - - // Do we need to look for message content? - if (this.readState == ReadState.Content && - !this.TryReadMessageContent(out messageContent)) - { - // If we don't have enough data yet to construct the content, keep reading - this.needsMoreData = true; - continue; - } - - // We've read a message now, break out of the loop - break; - } - - // Get the JObject for the JSON content - JObject messageObject = JObject.Parse(messageContent); - - // Load the message - Logger.Write( - LogLevel.Verbose, - string.Format( - "READ MESSAGE:\r\n\r\n{0}", - messageObject.ToString(Formatting.Indented))); - - // Return the parsed message - return this.messageSerializer.DeserializeMessage(messageObject); - } - - #endregion - - #region Private Methods - - private async Task ReadNextChunk() - { - // Do we need to resize the buffer? See if less than 1/4 of the space is left. - if (((double)(this.messageBuffer.Length - this.bufferEndOffset) / this.messageBuffer.Length) < 0.25) - { - // Double the size of the buffer - Array.Resize( - ref this.messageBuffer, - this.messageBuffer.Length * 2); - } - - // Read the next chunk into the message buffer - int readLength = - await this.inputStream.ReadAsync( - this.messageBuffer, - this.bufferEndOffset, - this.messageBuffer.Length - this.bufferEndOffset); - - this.bufferEndOffset += readLength; - - if (readLength == 0) - { - // If ReadAsync returns 0 then it means that the stream was - // closed unexpectedly (usually due to the client application - // ending suddenly). For now, just terminate the language - // server immediately. - // TODO: Provide a more graceful shutdown path - throw new EndOfStreamException( - "MessageReader's input stream ended unexpectedly, terminating."); - } - - return true; - } - - private bool TryReadMessageHeaders() - { - int scanOffset = this.readOffset; - - // Scan for the final double-newline that marks the - // end of the header lines - while (scanOffset + 3 < this.bufferEndOffset && - (this.messageBuffer[scanOffset] != CR || - this.messageBuffer[scanOffset + 1] != LF || - this.messageBuffer[scanOffset + 2] != CR || - this.messageBuffer[scanOffset + 3] != LF)) - { - scanOffset++; - } - - // No header or body separator found (e.g CRLFCRLF) - if (scanOffset + 3 >= this.bufferEndOffset) - { - return false; - } - - this.messageHeaders = new Dictionary(); - - var headers = - Encoding.ASCII - .GetString(this.messageBuffer, this.readOffset, scanOffset) - .Split(NewLineDelimiters, StringSplitOptions.RemoveEmptyEntries); - - // Read each header and store it in the dictionary - foreach (var header in headers) - { - int currentLength = header.IndexOf(':'); - if (currentLength == -1) - { - throw new ArgumentException("Message header must separate key and value using :"); - } - - var key = header.Substring(0, currentLength); - var value = header.Substring(currentLength + 1).Trim(); - this.messageHeaders[key] = value; - } - - // Make sure a Content-Length header was present, otherwise it - // is a fatal error - string contentLengthString = null; - if (!this.messageHeaders.TryGetValue("Content-Length", out contentLengthString)) - { - throw new MessageParseException("", "Fatal error: Content-Length header must be provided."); - } - - // Parse the content length to an integer - if (!int.TryParse(contentLengthString, out this.expectedContentLength)) - { - throw new MessageParseException("", "Fatal error: Content-Length value is not an integer."); - } - - // Skip past the headers plus the newline characters - this.readOffset += scanOffset + 4; - - // Done reading headers, now read content - this.readState = ReadState.Content; - - return true; - } - - private bool TryReadMessageContent(out string messageContent) - { - messageContent = null; - - // Do we have enough bytes to reach the expected length? - if ((this.bufferEndOffset - this.readOffset) < this.expectedContentLength) - { - return false; - } - - // Convert the message contents to a string using the specified encoding - messageContent = - this.messageEncoding.GetString( - this.messageBuffer, - this.readOffset, - this.expectedContentLength); - - // Move the remaining bytes to the front of the buffer for the next message - var remainingByteCount = this.bufferEndOffset - (this.expectedContentLength + this.readOffset); - Buffer.BlockCopy( - this.messageBuffer, - this.expectedContentLength + this.readOffset, - this.messageBuffer, - 0, - remainingByteCount); - - // Reset the offsets for the next read - this.readOffset = 0; - this.bufferEndOffset = remainingByteCount; - - // Done reading content, now look for headers - this.readState = ReadState.Headers; - - return true; - } - - #endregion - } -} diff --git a/ServiceHost/MessageProtocol/MessageWriter.cs b/ServiceHost/MessageProtocol/MessageWriter.cs deleted file mode 100644 index 96e13bcd..00000000 --- a/ServiceHost/MessageProtocol/MessageWriter.cs +++ /dev/null @@ -1,140 +0,0 @@ -// -// 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.EditorServices.Utility; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - public class MessageWriter - { - #region Private Fields - - private Stream outputStream; - private IMessageSerializer messageSerializer; - private AsyncLock writeLock = new AsyncLock(); - - private JsonSerializer contentSerializer = - JsonSerializer.Create( - Constants.JsonSerializerSettings); - - #endregion - - #region Constructors - - public MessageWriter( - Stream outputStream, - IMessageSerializer messageSerializer) - { - Validate.IsNotNull("streamWriter", outputStream); - Validate.IsNotNull("messageSerializer", messageSerializer); - - this.outputStream = outputStream; - this.messageSerializer = messageSerializer; - } - - #endregion - - #region Public Methods - - // TODO: This method should be made protected or private - - public async Task WriteMessage(Message messageToWrite) - { - Validate.IsNotNull("messageToWrite", messageToWrite); - - // Serialize the message - JObject messageObject = - this.messageSerializer.SerializeMessage( - messageToWrite); - - // Log the JSON representation of the message - Logger.Write( - LogLevel.Verbose, - string.Format( - "WRITE MESSAGE:\r\n\r\n{0}", - JsonConvert.SerializeObject( - messageObject, - Formatting.Indented, - Constants.JsonSerializerSettings))); - - string serializedMessage = - JsonConvert.SerializeObject( - messageObject, - Constants.JsonSerializerSettings); - - byte[] messageBytes = Encoding.UTF8.GetBytes(serializedMessage); - byte[] headerBytes = - Encoding.ASCII.GetBytes( - string.Format( - Constants.ContentLengthFormatString, - messageBytes.Length)); - - // Make sure only one call is writing at a time. You might be thinking - // "Why not use a normal lock?" We use an AsyncLock here so that the - // message loop doesn't get blocked while waiting for I/O to complete. - using (await this.writeLock.LockAsync()) - { - // Send the message - await this.outputStream.WriteAsync(headerBytes, 0, headerBytes.Length); - await this.outputStream.WriteAsync(messageBytes, 0, messageBytes.Length); - await this.outputStream.FlushAsync(); - } - } - - public async Task WriteRequest( - RequestType requestType, - TParams requestParams, - int requestId) - { - // Allow null content - JToken contentObject = - requestParams != null ? - JToken.FromObject(requestParams, contentSerializer) : - null; - - await this.WriteMessage( - Message.Request( - requestId.ToString(), - requestType.MethodName, - contentObject)); - } - - public async Task WriteResponse(TResult resultContent, string method, string requestId) - { - // Allow null content - JToken contentObject = - resultContent != null ? - JToken.FromObject(resultContent, contentSerializer) : - null; - - await this.WriteMessage( - Message.Response( - requestId, - method, - contentObject)); - } - - public async Task WriteEvent(EventType eventType, TParams eventParams) - { - // Allow null content - JToken contentObject = - eventParams != null ? - JToken.FromObject(eventParams, contentSerializer) : - null; - - await this.WriteMessage( - Message.Event( - eventType.MethodName, - contentObject)); - } - - #endregion - } -} diff --git a/ServiceHost/MessageProtocol/ProtocolEndpoint.cs b/ServiceHost/MessageProtocol/ProtocolEndpoint.cs deleted file mode 100644 index daead186..00000000 --- a/ServiceHost/MessageProtocol/ProtocolEndpoint.cs +++ /dev/null @@ -1,313 +0,0 @@ -// -// 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.EditorServices.Protocol.MessageProtocol.Channel; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - /// - /// Provides behavior for a client or server endpoint that - /// communicates using the specified protocol. - /// - public class ProtocolEndpoint : IMessageSender - { - private bool isStarted; - private int currentMessageId; - private ChannelBase protocolChannel; - private MessageProtocolType messageProtocolType; - private TaskCompletionSource endpointExitedTask; - private SynchronizationContext originalSynchronizationContext; - - private Dictionary> pendingRequests = - new Dictionary>(); - - /// - /// Gets the MessageDispatcher which allows registration of - /// handlers for requests, responses, and events that are - /// transmitted through the channel. - /// - protected MessageDispatcher MessageDispatcher { get; set; } - - /// - /// Initializes an instance of the protocol server using the - /// specified channel for communication. - /// - /// - /// The channel to use for communication with the connected endpoint. - /// - /// - /// The type of message protocol used by the endpoint. - /// - public ProtocolEndpoint( - ChannelBase protocolChannel, - MessageProtocolType messageProtocolType) - { - this.protocolChannel = protocolChannel; - this.messageProtocolType = messageProtocolType; - this.originalSynchronizationContext = SynchronizationContext.Current; - } - - /// - /// Starts the language server client and sends the Initialize method. - /// - /// A Task that can be awaited for initialization to complete. - public async Task Start() - { - if (!this.isStarted) - { - // Start the provided protocol channel - this.protocolChannel.Start(this.messageProtocolType); - - // Start the message dispatcher - this.MessageDispatcher = new MessageDispatcher(this.protocolChannel); - - // Set the handler for any message responses that come back - this.MessageDispatcher.SetResponseHandler(this.HandleResponse); - - // Listen for unhandled exceptions from the dispatcher - this.MessageDispatcher.UnhandledException += MessageDispatcher_UnhandledException; - - // Notify implementation about endpoint start - await this.OnStart(); - - // Wait for connection and notify the implementor - // NOTE: This task is not meant to be awaited. - Task waitTask = - this.protocolChannel - .WaitForConnection() - .ContinueWith( - async (t) => - { - // Start the MessageDispatcher - this.MessageDispatcher.Start(); - await this.OnConnect(); - }); - - // Endpoint is now started - this.isStarted = true; - } - } - - public void WaitForExit() - { - this.endpointExitedTask = new TaskCompletionSource(); - this.endpointExitedTask.Task.Wait(); - } - - public async Task Stop() - { - if (this.isStarted) - { - // Make sure no future calls try to stop the endpoint during shutdown - this.isStarted = false; - - // Stop the implementation first - await this.OnStop(); - - // Stop the dispatcher and channel - this.MessageDispatcher.Stop(); - this.protocolChannel.Stop(); - - // Notify anyone waiting for exit - if (this.endpointExitedTask != null) - { - this.endpointExitedTask.SetResult(true); - } - } - } - - #region Message Sending - - /// - /// Sends a request to the server - /// - /// - /// - /// - /// - /// - public Task SendRequest( - RequestType requestType, - TParams requestParams) - { - return this.SendRequest(requestType, requestParams, true); - } - - public async Task SendRequest( - RequestType requestType, - TParams requestParams, - bool waitForResponse) - { - if (!this.protocolChannel.IsConnected) - { - throw new InvalidOperationException("SendRequest called when ProtocolChannel was not yet connected"); - } - - this.currentMessageId++; - - TaskCompletionSource responseTask = null; - - if (waitForResponse) - { - responseTask = new TaskCompletionSource(); - this.pendingRequests.Add( - this.currentMessageId.ToString(), - responseTask); - } - - await this.protocolChannel.MessageWriter.WriteRequest( - requestType, - requestParams, - this.currentMessageId); - - if (responseTask != null) - { - var responseMessage = await responseTask.Task; - - return - responseMessage.Contents != null ? - responseMessage.Contents.ToObject() : - default(TResult); - } - else - { - // TODO: Better default value here? - return default(TResult); - } - } - - /// - /// Sends an event to the channel's endpoint. - /// - /// The event parameter type. - /// The type of event being sent. - /// The event parameters being sent. - /// A Task that tracks completion of the send operation. - public Task SendEvent( - EventType eventType, - TParams eventParams) - { - if (!this.protocolChannel.IsConnected) - { - throw new InvalidOperationException("SendEvent called when ProtocolChannel was not yet connected"); - } - - // Some events could be raised from a different thread. - // To ensure that messages are written serially, dispatch - // dispatch the SendEvent call to the message loop thread. - - if (!this.MessageDispatcher.InMessageLoopThread) - { - TaskCompletionSource writeTask = new TaskCompletionSource(); - - this.MessageDispatcher.SynchronizationContext.Post( - async (obj) => - { - await this.protocolChannel.MessageWriter.WriteEvent( - eventType, - eventParams); - - writeTask.SetResult(true); - }, null); - - return writeTask.Task; - } - else - { - return this.protocolChannel.MessageWriter.WriteEvent( - eventType, - eventParams); - } - } - - #endregion - - #region Message Handling - - public void SetRequestHandler( - RequestType requestType, - Func, Task> requestHandler) - { - this.MessageDispatcher.SetRequestHandler( - requestType, - requestHandler); - } - - public void SetEventHandler( - EventType eventType, - Func eventHandler) - { - this.MessageDispatcher.SetEventHandler( - eventType, - eventHandler, - false); - } - - public void SetEventHandler( - EventType eventType, - Func eventHandler, - bool overrideExisting) - { - this.MessageDispatcher.SetEventHandler( - eventType, - eventHandler, - overrideExisting); - } - - private void HandleResponse(Message responseMessage) - { - TaskCompletionSource pendingRequestTask = null; - - if (this.pendingRequests.TryGetValue(responseMessage.Id, out pendingRequestTask)) - { - pendingRequestTask.SetResult(responseMessage); - this.pendingRequests.Remove(responseMessage.Id); - } - } - - #endregion - - #region Subclass Lifetime Methods - - protected virtual Task OnStart() - { - return Task.FromResult(true); - } - - protected virtual Task OnConnect() - { - return Task.FromResult(true); - } - - protected virtual Task OnStop() - { - return Task.FromResult(true); - } - - #endregion - - #region Event Handlers - - private void MessageDispatcher_UnhandledException(object sender, Exception e) - { - if (this.endpointExitedTask != null) - { - this.endpointExitedTask.SetException(e); - } - - else if (this.originalSynchronizationContext != null) - { - this.originalSynchronizationContext.Post(o => { throw e; }, null); - } - } - - #endregion - } -} - diff --git a/ServiceHost/MessageProtocol/RequestContext.cs b/ServiceHost/MessageProtocol/RequestContext.cs deleted file mode 100644 index a35bb136..00000000 --- a/ServiceHost/MessageProtocol/RequestContext.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using Newtonsoft.Json.Linq; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - public class RequestContext - { - private Message requestMessage; - private MessageWriter messageWriter; - - public RequestContext(Message requestMessage, MessageWriter messageWriter) - { - this.requestMessage = requestMessage; - this.messageWriter = messageWriter; - } - - public async Task SendResult(TResult resultDetails) - { - await this.messageWriter.WriteResponse( - resultDetails, - requestMessage.Method, - requestMessage.Id); - } - - public async Task SendEvent(EventType eventType, TParams eventParams) - { - await this.messageWriter.WriteEvent( - eventType, - eventParams); - } - - public async Task SendError(object errorDetails) - { - await this.messageWriter.WriteMessage( - Message.ResponseError( - requestMessage.Id, - requestMessage.Method, - JToken.FromObject(errorDetails))); - } - } -} - diff --git a/ServiceHost/MessageProtocol/RequestType.cs b/ServiceHost/MessageProtocol/RequestType.cs deleted file mode 100644 index 29fc11c5..00000000 --- a/ServiceHost/MessageProtocol/RequestType.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol -{ - [DebuggerDisplay("RequestType MethodName = {MethodName}")] - public class RequestType - { - public string MethodName { get; private set; } - - public static RequestType Create(string typeName) - { - return new RequestType() - { - MethodName = typeName - }; - } - } -} - diff --git a/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs b/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs deleted file mode 100644 index fa1d1518..00000000 --- a/ServiceHost/MessageProtocol/Serializers/JsonRpcMessageSerializer.cs +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using Newtonsoft.Json.Linq; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Serializers -{ - /// - /// Serializes messages in the JSON RPC format. Used primarily - /// for language servers. - /// - public class JsonRpcMessageSerializer : IMessageSerializer - { - public JObject SerializeMessage(Message message) - { - JObject messageObject = new JObject(); - - messageObject.Add("jsonrpc", JToken.FromObject("2.0")); - - if (message.MessageType == MessageType.Request) - { - messageObject.Add("id", JToken.FromObject(message.Id)); - messageObject.Add("method", message.Method); - messageObject.Add("params", message.Contents); - } - else if (message.MessageType == MessageType.Event) - { - messageObject.Add("method", message.Method); - messageObject.Add("params", message.Contents); - } - else if (message.MessageType == MessageType.Response) - { - messageObject.Add("id", JToken.FromObject(message.Id)); - - if (message.Error != null) - { - // Write error - messageObject.Add("error", message.Error); - } - else - { - // Write result - messageObject.Add("result", message.Contents); - } - } - - return messageObject; - } - - public Message DeserializeMessage(JObject messageJson) - { - // TODO: Check for jsonrpc version - - JToken token = null; - if (messageJson.TryGetValue("id", out token)) - { - // Message is a Request or Response - string messageId = token.ToString(); - - if (messageJson.TryGetValue("result", out token)) - { - return Message.Response(messageId, null, token); - } - else if (messageJson.TryGetValue("error", out token)) - { - return Message.ResponseError(messageId, null, token); - } - else - { - JToken messageParams = null; - messageJson.TryGetValue("params", out messageParams); - - if (!messageJson.TryGetValue("method", out token)) - { - // TODO: Throw parse error - } - - return Message.Request(messageId, token.ToString(), messageParams); - } - } - else - { - // Messages without an id are events - JToken messageParams = token; - messageJson.TryGetValue("params", out messageParams); - - if (!messageJson.TryGetValue("method", out token)) - { - // TODO: Throw parse error - } - - return Message.Event(token.ToString(), messageParams); - } - } - } -} - diff --git a/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs b/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs deleted file mode 100644 index 941e249a..00000000 --- a/ServiceHost/MessageProtocol/Serializers/V8MessageSerializer.cs +++ /dev/null @@ -1,113 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using Newtonsoft.Json.Linq; -using System; - -namespace Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Serializers -{ - /// - /// Serializes messages in the V8 format. Used primarily for debug adapters. - /// - public class V8MessageSerializer : IMessageSerializer - { - public JObject SerializeMessage(Message message) - { - JObject messageObject = new JObject(); - - if (message.MessageType == MessageType.Request) - { - messageObject.Add("type", JToken.FromObject("request")); - messageObject.Add("seq", JToken.FromObject(message.Id)); - messageObject.Add("command", message.Method); - messageObject.Add("arguments", message.Contents); - } - else if (message.MessageType == MessageType.Event) - { - messageObject.Add("type", JToken.FromObject("event")); - messageObject.Add("event", message.Method); - messageObject.Add("body", message.Contents); - } - else if (message.MessageType == MessageType.Response) - { - messageObject.Add("type", JToken.FromObject("response")); - messageObject.Add("request_seq", JToken.FromObject(message.Id)); - messageObject.Add("command", message.Method); - - if (message.Error != null) - { - // Write error - messageObject.Add("success", JToken.FromObject(false)); - messageObject.Add("message", message.Error); - } - else - { - // Write result - messageObject.Add("success", JToken.FromObject(true)); - messageObject.Add("body", message.Contents); - } - } - - return messageObject; - } - - public Message DeserializeMessage(JObject messageJson) - { - JToken token = null; - - if (messageJson.TryGetValue("type", out token)) - { - string messageType = token.ToString(); - - if (string.Equals("request", messageType, StringComparison.CurrentCultureIgnoreCase)) - { - return Message.Request( - messageJson.GetValue("seq").ToString(), - messageJson.GetValue("command").ToString(), - messageJson.GetValue("arguments")); - } - else if (string.Equals("response", messageType, StringComparison.CurrentCultureIgnoreCase)) - { - if (messageJson.TryGetValue("success", out token)) - { - // Was the response for a successful request? - if (token.ToObject() == true) - { - return Message.Response( - messageJson.GetValue("request_seq").ToString(), - messageJson.GetValue("command").ToString(), - messageJson.GetValue("body")); - } - else - { - return Message.ResponseError( - messageJson.GetValue("request_seq").ToString(), - messageJson.GetValue("command").ToString(), - messageJson.GetValue("message")); - } - } - else - { - // TODO: Parse error - } - - } - else if (string.Equals("event", messageType, StringComparison.CurrentCultureIgnoreCase)) - { - return Message.Event( - messageJson.GetValue("event").ToString(), - messageJson.GetValue("body")); - } - else - { - return Message.Unknown(); - } - } - - return Message.Unknown(); - } - } -} - diff --git a/ServiceHost/Program.cs b/ServiceHost/Program.cs deleted file mode 100644 index 6bfd0f24..00000000 --- a/ServiceHost/Program.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using Microsoft.SqlTools.EditorServices.Protocol.Server; -using Microsoft.SqlTools.EditorServices.Session; -using Microsoft.SqlTools.EditorServices.Utility; - -namespace Microsoft.SqlTools.ServiceHost -{ - /// - /// Main application class for SQL Tools API Service Host executable - /// - class Program - { - /// - /// Main entry point into the SQL Tools API Service Host - /// - static void Main(string[] args) - { - // turn on Verbose logging during early development - // we need to switch to Normal when preparing for public preview - Logger.Initialize(minimumLogLevel: LogLevel.Verbose); - Logger.Write(LogLevel.Normal, "Starting SQL Tools Service Host"); - - const string hostName = "SQL Tools Service Host"; - const string hostProfileId = "SQLToolsService"; - Version hostVersion = new Version(1,0); - - // set up the host details and profile paths - var hostDetails = new HostDetails(hostName, hostProfileId, hostVersion); - var profilePaths = new ProfilePaths(hostProfileId, "baseAllUsersPath", "baseCurrentUserPath"); - - // create and run the language server - var languageServer = new LanguageServer(hostDetails, profilePaths); - languageServer.Start().Wait(); - languageServer.WaitForExit(); - } - } -} diff --git a/ServiceHost/Properties/AssemblyInfo.cs b/ServiceHost/Properties/AssemblyInfo.cs deleted file mode 100644 index 27c1daba..00000000 --- a/ServiceHost/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SqlTools Editor Services Host Protocol Library")] -[assembly: AssemblyDescription("Provides message types and client/server APIs for the SqlTools Editor Services JSON protocol.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("SqlTools Editor Services")] -[assembly: AssemblyCopyright("� Microsoft Corporation. All rights reserved.")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("78caf6c3-5955-4b15-a302-2bd6b7871d5b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: AssemblyInformationalVersion("1.0.0.0")] - -[assembly: InternalsVisibleTo("Microsoft.SqlTools.EditorServices.Test.Protocol")] diff --git a/ServiceHost/Server/LanguageServer.cs b/ServiceHost/Server/LanguageServer.cs deleted file mode 100644 index d6719141..00000000 --- a/ServiceHost/Server/LanguageServer.cs +++ /dev/null @@ -1,517 +0,0 @@ -// -// 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.EditorServices.Protocol.LanguageServer; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; -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; -using System.Threading; -using System.Linq; -using System; - -namespace Microsoft.SqlTools.EditorServices.Protocol.Server -{ - /// - /// SQL Tools VS Code Language Server request handler - /// - public class LanguageServer : LanguageServerBase - { - private static CancellationTokenSource existingRequestCancellation; - - private LanguageServerSettings currentSettings = new LanguageServerSettings(); - - 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); - } - - /// - /// Initialize the VS Code request/response callbacks - /// - protected override void Initialize() - { - // Register all supported message types - this.SetRequestHandler(InitializeRequest.Type, this.HandleInitializeRequest); - this.SetEventHandler(DidChangeTextDocumentNotification.Type, this.HandleDidChangeTextDocumentNotification); - this.SetEventHandler(DidOpenTextDocumentNotification.Type, this.HandleDidOpenTextDocumentNotification); - this.SetEventHandler(DidCloseTextDocumentNotification.Type, this.HandleDidCloseTextDocumentNotification); - this.SetEventHandler(DidChangeConfigurationNotification.Type, this.HandleDidChangeConfigurationNotification); - - this.SetRequestHandler(DefinitionRequest.Type, this.HandleDefinitionRequest); - this.SetRequestHandler(ReferencesRequest.Type, this.HandleReferencesRequest); - this.SetRequestHandler(CompletionRequest.Type, this.HandleCompletionRequest); - this.SetRequestHandler(CompletionResolveRequest.Type, this.HandleCompletionResolveRequest); - this.SetRequestHandler(SignatureHelpRequest.Type, this.HandleSignatureHelpRequest); - this.SetRequestHandler(DocumentHighlightRequest.Type, this.HandleDocumentHighlightRequest); - this.SetRequestHandler(HoverRequest.Type, this.HandleHoverRequest); - this.SetRequestHandler(DocumentSymbolRequest.Type, this.HandleDocumentSymbolRequest); - this.SetRequestHandler(WorkspaceSymbolRequest.Type, this.HandleWorkspaceSymbolRequest); - } - - /// - /// Handles the shutdown event for the Language 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); - } - - /// - /// Handles the initialization request - /// - /// - /// - /// - protected async Task HandleInitializeRequest( - InitializeRequest initializeParams, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleDidChangeTextDocumentNotification"); - - // Grab the workspace path from the parameters - editorSession.Workspace.WorkspacePath = initializeParams.RootPath; - - await requestContext.SendResult( - new InitializeResult - { - Capabilities = new ServerCapabilities - { - TextDocumentSync = TextDocumentSyncKind.Incremental, - DefinitionProvider = true, - ReferencesProvider = true, - DocumentHighlightProvider = true, - DocumentSymbolProvider = true, - WorkspaceSymbolProvider = true, - HoverProvider = true, - CompletionProvider = new CompletionOptions - { - ResolveProvider = true, - TriggerCharacters = new string[] { ".", "-", ":", "\\" } - }, - SignatureHelpProvider = new SignatureHelpOptions - { - TriggerCharacters = new string[] { " " } // TODO: Other characters here? - } - } - }); - } - - /// - /// Handles text document change events - /// - /// - /// - /// - protected Task HandleDidChangeTextDocumentNotification( - DidChangeTextDocumentParams textChangeParams, - EventContext eventContext) - { - 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.Verbose, msg.ToString()); - - this.RunScriptDiagnostics( - changedFiles.ToArray(), - editorSession, - eventContext); - - return Task.FromResult(true); - } - - protected Task HandleDidOpenTextDocumentNotification( - DidOpenTextDocumentNotification openParams, - EventContext eventContext) - { - Logger.Write(LogLevel.Verbose, "HandleDidOpenTextDocumentNotification"); - return Task.FromResult(true); - } - - protected Task HandleDidCloseTextDocumentNotification( - TextDocumentIdentifier closeParams, - EventContext eventContext) - { - Logger.Write(LogLevel.Verbose, "HandleDidCloseTextDocumentNotification"); - return Task.FromResult(true); - } - - /// - /// Handles the configuration change event - /// - /// - /// - protected async Task HandleDidChangeConfigurationNotification( - DidChangeConfigurationParams configChangeParams, - EventContext eventContext) - { - Logger.Write(LogLevel.Verbose, "HandleDidChangeConfigurationNotification"); - - bool oldLoadProfiles = this.currentSettings.EnableProfileLoading; - bool oldScriptAnalysisEnabled = - this.currentSettings.ScriptAnalysis.Enable.HasValue; - string oldScriptAnalysisSettingsPath = - this.currentSettings.ScriptAnalysis.SettingsPath; - - this.currentSettings.Update( - configChangeParams.Settings.SqlTools, - this.editorSession.Workspace.WorkspacePath); - - // If script analysis settings have changed we need to clear & possibly update the current diagnostic records. - if ((oldScriptAnalysisEnabled != this.currentSettings.ScriptAnalysis.Enable)) - { - // If the user just turned off script analysis or changed the settings path, send a diagnostics - // event to clear the analysis markers that they already have. - if (!this.currentSettings.ScriptAnalysis.Enable.Value) - { - ScriptFileMarker[] emptyAnalysisDiagnostics = new ScriptFileMarker[0]; - - foreach (var scriptFile in editorSession.Workspace.GetOpenedFiles()) - { - await PublishScriptDiagnostics( - scriptFile, - emptyAnalysisDiagnostics, - eventContext); - } - } - else - { - await this.RunScriptDiagnostics( - this.editorSession.Workspace.GetOpenedFiles(), - this.editorSession, - eventContext); - } - } - - await Task.FromResult(true); - } - - protected async Task HandleDefinitionRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleDefinitionRequest"); - await Task.FromResult(true); - } - - protected async Task HandleReferencesRequest( - ReferencesParams referencesParams, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleReferencesRequest"); - await Task.FromResult(true); - } - - protected async Task HandleCompletionRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleCompletionRequest"); - await Task.FromResult(true); - } - - protected async Task HandleCompletionResolveRequest( - CompletionItem completionItem, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleCompletionResolveRequest"); - await Task.FromResult(true); - } - - protected async Task HandleSignatureHelpRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleSignatureHelpRequest"); - await Task.FromResult(true); - } - - protected async Task HandleDocumentHighlightRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleDocumentHighlightRequest"); - await Task.FromResult(true); - } - - protected async Task HandleHoverRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleHoverRequest"); - await Task.FromResult(true); - } - - protected async Task HandleDocumentSymbolRequest( - TextDocumentIdentifier textDocumentIdentifier, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleDocumentSymbolRequest"); - await Task.FromResult(true); - } - - protected async Task HandleWorkspaceSymbolRequest( - WorkspaceSymbolParams workspaceSymbolParams, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleWorkspaceSymbolRequest"); - await Task.FromResult(true); - } - - /// - /// Runs script diagnostics on changed files - /// - /// - /// - /// - private Task RunScriptDiagnostics( - ScriptFile[] filesToAnalyze, - EditorSession editorSession, - EventContext eventContext) - { - if (!this.currentSettings.ScriptAnalysis.Enable.Value) - { - // If the user has disabled script analysis, skip it entirely - return Task.FromResult(true); - } - - // If there's an existing task, attempt to cancel it - try - { - if (existingRequestCancellation != null) - { - // Try to cancel the request - existingRequestCancellation.Cancel(); - - // If cancellation didn't throw an exception, - // clean up the existing token - existingRequestCancellation.Dispose(); - existingRequestCancellation = null; - } - } - catch (Exception e) - { - Logger.Write( - LogLevel.Error, - string.Format( - "Exception while cancelling analysis task:\n\n{0}", - e.ToString())); - - TaskCompletionSource cancelTask = new TaskCompletionSource(); - cancelTask.SetCanceled(); - return cancelTask.Task; - } - - // Create a fresh cancellation token and then start the task. - // We create this on a different TaskScheduler so that we - // don't block the main message loop thread. - existingRequestCancellation = new CancellationTokenSource(); - Task.Factory.StartNew( - () => - DelayThenInvokeDiagnostics( - 750, - filesToAnalyze, - editorSession, - eventContext, - existingRequestCancellation.Token), - CancellationToken.None, - TaskCreationOptions.None, - TaskScheduler.Default); - - return Task.FromResult(true); - } - - /// - /// Actually run the script diagnostics after waiting for some small delay - /// - /// - /// - /// - /// - /// - private static async Task DelayThenInvokeDiagnostics( - int delayMilliseconds, - ScriptFile[] filesToAnalyze, - EditorSession editorSession, - EventContext eventContext, - CancellationToken cancellationToken) - { - // First of all, wait for the desired delay period before - // analyzing the provided list of files - try - { - await Task.Delay(delayMilliseconds, cancellationToken); - } - catch (TaskCanceledException) - { - // If the task is cancelled, exit directly - return; - } - - // If we've made it past the delay period then we don't care - // about the cancellation token anymore. This could happen - // when the user stops typing for long enough that the delay - // period ends but then starts typing while analysis is going - // on. It makes sense to send back the results from the first - // delay period while the second one is ticking away. - - // Get the requested files - foreach (ScriptFile scriptFile in filesToAnalyze) - { - ScriptFileMarker[] semanticMarkers = null; - if (editorSession.LanguageService != null) - { - Logger.Write(LogLevel.Verbose, "Analyzing script file: " + scriptFile.FilePath); - semanticMarkers = editorSession.LanguageService.GetSemanticMarkers(scriptFile); - Logger.Write(LogLevel.Verbose, "Analysis complete."); - } - else - { - // Semantic markers aren't available if the AnalysisService - // isn't available - semanticMarkers = new ScriptFileMarker[0]; - } - - await PublishScriptDiagnostics( - scriptFile, - semanticMarkers, - eventContext); - } - } - - /// - /// Send the diagnostic results back to the host application - /// - /// - /// - /// - private static async Task PublishScriptDiagnostics( - ScriptFile scriptFile, - ScriptFileMarker[] semanticMarkers, - EventContext eventContext) - { - var allMarkers = scriptFile.SyntaxMarkers != null - ? scriptFile.SyntaxMarkers.Concat(semanticMarkers) - : semanticMarkers; - - // Always send syntax and semantic errors. We want to - // make sure no out-of-date markers are being displayed. - await eventContext.SendEvent( - PublishDiagnosticsNotification.Type, - new PublishDiagnosticsNotification - { - Uri = scriptFile.ClientFilePath, - Diagnostics = - allMarkers - .Select(GetDiagnosticFromMarker) - .ToArray() - }); - } - - /// - /// Convert a ScriptFileMarker to a Diagnostic that is Language Service compatible - /// - /// - /// - private static Diagnostic GetDiagnosticFromMarker(ScriptFileMarker scriptFileMarker) - { - return new Diagnostic - { - Severity = MapDiagnosticSeverity(scriptFileMarker.Level), - Message = scriptFileMarker.Message, - Range = new Range - { - // TODO: What offsets should I use? - Start = new Position - { - Line = scriptFileMarker.ScriptRegion.StartLineNumber - 1, - Character = scriptFileMarker.ScriptRegion.StartColumnNumber - 1 - }, - End = new Position - { - Line = scriptFileMarker.ScriptRegion.EndLineNumber - 1, - Character = scriptFileMarker.ScriptRegion.EndColumnNumber - 1 - } - } - }; - } - - /// - /// Map ScriptFileMarker severity to Diagnostic severity - /// - /// - private static DiagnosticSeverity MapDiagnosticSeverity(ScriptFileMarkerLevel markerLevel) - { - switch (markerLevel) - { - case ScriptFileMarkerLevel.Error: - return DiagnosticSeverity.Error; - - case ScriptFileMarkerLevel.Warning: - return DiagnosticSeverity.Warning; - - case ScriptFileMarkerLevel.Information: - return DiagnosticSeverity.Information; - - default: - return DiagnosticSeverity.Error; - } - } - - /// - /// Switch from 0-based offsets to 1 based offsets - /// - /// - /// - private static FileChange GetFileChangeDetails(Range changeRange, string insertString) - { - // The protocol's positions are zero-based so add 1 to all offsets - return new FileChange - { - InsertString = insertString, - Line = changeRange.Start.Line + 1, - Offset = changeRange.Start.Character + 1, - EndLine = changeRange.End.Line + 1, - EndOffset = changeRange.End.Character + 1 - }; - } - } -} diff --git a/ServiceHost/Server/LanguageServerBase.cs b/ServiceHost/Server/LanguageServerBase.cs deleted file mode 100644 index 0128484b..00000000 --- a/ServiceHost/Server/LanguageServerBase.cs +++ /dev/null @@ -1,84 +0,0 @@ -// -// 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.EditorServices.Protocol.LanguageServer; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Channel; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.Server -{ - public abstract class LanguageServerBase : ProtocolEndpoint - { - private bool isStarted; - private ChannelBase serverChannel; - private TaskCompletionSource serverExitedTask; - - public LanguageServerBase(ChannelBase serverChannel) : - base(serverChannel, MessageProtocolType.LanguageServer) - { - this.serverChannel = serverChannel; - } - - protected override Task OnStart() - { - // Register handlers for server lifetime messages - this.SetRequestHandler(ShutdownRequest.Type, this.HandleShutdownRequest); - this.SetEventHandler(ExitNotification.Type, this.HandleExitNotification); - - // Initialize the implementation class - this.Initialize(); - - return Task.FromResult(true); - } - - protected override async Task OnStop() - { - await this.Shutdown(); - } - - /// - /// Overridden by the subclass to provide initialization - /// logic after the server channel is started. - /// - protected abstract void Initialize(); - - /// - /// Can be overridden by the subclass to provide shutdown - /// logic before the server exits. Subclasses do not need - /// to invoke or return the value of the base implementation. - /// - protected virtual Task Shutdown() - { - // No default implementation yet. - return Task.FromResult(true); - } - - private async Task HandleShutdownRequest( - object shutdownParams, - RequestContext requestContext) - { - // Allow the implementor to shut down gracefully - await this.Shutdown(); - - await requestContext.SendResult(new object()); - } - - private async Task HandleExitNotification( - object exitParams, - EventContext eventContext) - { - // Stop the server channel - await this.Stop(); - - // Notify any waiter that the server has exited - if (this.serverExitedTask != null) - { - this.serverExitedTask.SetResult(true); - } - } - } -} - diff --git a/ServiceHost/Server/LanguageServerEditorOperations.cs b/ServiceHost/Server/LanguageServerEditorOperations.cs deleted file mode 100644 index e5714b19..00000000 --- a/ServiceHost/Server/LanguageServerEditorOperations.cs +++ /dev/null @@ -1,114 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -#if false -using Microsoft.SqlTools.EditorServices.Extensions; -using Microsoft.SqlTools.EditorServices.Protocol.LanguageServer; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Protocol.Server -{ - internal class LanguageServerEditorOperations : IEditorOperations - { - private EditorSession editorSession; - private IMessageSender messageSender; - - public LanguageServerEditorOperations( - EditorSession editorSession, - IMessageSender messageSender) - { - this.editorSession = editorSession; - this.messageSender = messageSender; - } - - public async Task GetEditorContext() - { - ClientEditorContext clientContext = - await this.messageSender.SendRequest( - GetEditorContextRequest.Type, - new GetEditorContextRequest(), - true); - - return this.ConvertClientEditorContext(clientContext); - } - - public async Task InsertText(string filePath, string text, BufferRange insertRange) - { - await this.messageSender.SendRequest( - InsertTextRequest.Type, - new InsertTextRequest - { - FilePath = filePath, - InsertText = text, - InsertRange = - new Range - { - Start = new Position - { - Line = insertRange.Start.Line - 1, - Character = insertRange.Start.Column - 1 - }, - End = new Position - { - Line = insertRange.End.Line - 1, - Character = insertRange.End.Column - 1 - } - } - }, false); - - // TODO: Set the last param back to true! - } - - public Task SetSelection(BufferRange selectionRange) - { - return this.messageSender.SendRequest( - SetSelectionRequest.Type, - new SetSelectionRequest - { - SelectionRange = - new Range - { - Start = new Position - { - Line = selectionRange.Start.Line - 1, - Character = selectionRange.Start.Column - 1 - }, - End = new Position - { - Line = selectionRange.End.Line - 1, - Character = selectionRange.End.Column - 1 - } - } - }, true); - } - - public EditorContext ConvertClientEditorContext( - ClientEditorContext clientContext) - { - return - new EditorContext( - this, - this.editorSession.Workspace.GetFile(clientContext.CurrentFilePath), - new BufferPosition( - clientContext.CursorPosition.Line + 1, - clientContext.CursorPosition.Character + 1), - new BufferRange( - clientContext.SelectionRange.Start.Line + 1, - clientContext.SelectionRange.Start.Character + 1, - clientContext.SelectionRange.End.Line + 1, - clientContext.SelectionRange.End.Character + 1)); - } - - public Task OpenFile(string filePath) - { - return - this.messageSender.SendRequest( - OpenFileRequest.Type, - filePath, - true); - } - } -} -#endif \ No newline at end of file diff --git a/ServiceHost/Server/LanguageServerSettings.cs b/ServiceHost/Server/LanguageServerSettings.cs deleted file mode 100644 index be09984a..00000000 --- a/ServiceHost/Server/LanguageServerSettings.cs +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.IO; -using Microsoft.SqlTools.EditorServices.Utility; - -namespace Microsoft.SqlTools.EditorServices.Protocol.Server -{ - public class LanguageServerSettings - { - public bool EnableProfileLoading { get; set; } - - public ScriptAnalysisSettings ScriptAnalysis { get; set; } - - public LanguageServerSettings() - { - this.ScriptAnalysis = new ScriptAnalysisSettings(); - } - - public void Update(LanguageServerSettings settings, string workspaceRootPath) - { - if (settings != null) - { - this.EnableProfileLoading = settings.EnableProfileLoading; - this.ScriptAnalysis.Update(settings.ScriptAnalysis, workspaceRootPath); - } - } - } - - - public class ScriptAnalysisSettings - { - public bool? Enable { get; set; } - - public string SettingsPath { get; set; } - - public ScriptAnalysisSettings() - { - this.Enable = true; - } - - public void Update(ScriptAnalysisSettings settings, string workspaceRootPath) - { - if (settings != null) - { - this.Enable = settings.Enable; - - string settingsPath = settings.SettingsPath; - - if (string.IsNullOrWhiteSpace(settingsPath)) - { - settingsPath = null; - } - else if (!Path.IsPathRooted(settingsPath)) - { - if (string.IsNullOrEmpty(workspaceRootPath)) - { - // The workspace root path could be an empty string - // when the user has opened a SqlTools script file - // without opening an entire folder (workspace) first. - // In this case we should just log an error and let - // the specified settings path go through even though - // it will fail to load. - Logger.Write( - LogLevel.Error, - "Could not resolve Script Analyzer settings path due to null or empty workspaceRootPath."); - } - else - { - settingsPath = Path.GetFullPath(Path.Combine(workspaceRootPath, settingsPath)); - } - } - - this.SettingsPath = settingsPath; - } - } - } - - - public class LanguageServerSettingsWrapper - { - // NOTE: This property is capitalized as 'SqlTools' because the - // mode name sent from the client is written as 'SqlTools' and - // JSON.net is using camelCasing. - - public LanguageServerSettings SqlTools { get; set; } - } -} diff --git a/ServiceHost/Session/EditorSession.cs b/ServiceHost/Session/EditorSession.cs deleted file mode 100644 index 3c592a8f..00000000 --- a/ServiceHost/Session/EditorSession.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using Microsoft.SqlTools.EditorServices.Session; -using Microsoft.SqlTools.LanguageSupport; - -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 : IDisposable - { - #region Properties - - /// - /// Gets the Workspace instance for this session. - /// - public Workspace Workspace { get; private set; } - - /// - /// Gets or sets the Language Service - /// - /// - public LanguageService LanguageService { get; set; } - - /// - /// Gets the SqlToolsContext instance for this session. - /// - 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); - - // 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 - - } -} diff --git a/ServiceHost/Session/HostDetails.cs b/ServiceHost/Session/HostDetails.cs deleted file mode 100644 index 1a5fc80d..00000000 --- a/ServiceHost/Session/HostDetails.cs +++ /dev/null @@ -1,92 +0,0 @@ -// -// 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 -{ - /// - /// Contains details about the current host application (most - /// likely the editor which is using the host process). - /// - public class HostDetails - { - #region Constants - - /// - /// The default host name for SqlTools Editor Services. Used - /// if no host name is specified by the host application. - /// - public const string DefaultHostName = "SqlTools Editor Services Host"; - - /// - /// The default host ID for SqlTools Editor Services. Used - /// for the host-specific profile path if no host ID is specified. - /// - public const string DefaultHostProfileId = "Microsoft.SqlToolsEditorServices"; - - /// - /// The default host version for SqlTools Editor Services. If - /// no version is specified by the host application, we use 0.0.0 - /// to indicate a lack of version. - /// - public static readonly Version DefaultHostVersion = new Version("0.0.0"); - - /// - /// The default host details in a HostDetails object. - /// - public static readonly HostDetails Default = new HostDetails(null, null, null); - - #endregion - - #region Properties - - /// - /// Gets the name of the host. - /// - public string Name { get; private set; } - - /// - /// Gets the profile ID of the host, used to determine the - /// host-specific profile path. - /// - public string ProfileId { get; private set; } - - /// - /// Gets the version of the host. - /// - public Version Version { get; private set; } - - #endregion - - #region Constructors - - /// - /// Creates an instance of the HostDetails class. - /// - /// - /// The display name for the host, typically in the form of - /// "[Application Name] Host". - /// - /// - /// The identifier of the SqlTools host to use for its profile path. - /// loaded. Used to resolve a profile path of the form 'X_profile.ps1' - /// where 'X' represents the value of hostProfileId. If null, a default - /// will be used. - /// - /// The host application's version. - public HostDetails( - string name, - string profileId, - Version version) - { - this.Name = name ?? DefaultHostName; - this.ProfileId = profileId ?? DefaultHostProfileId; - this.Version = version ?? DefaultHostVersion; - } - - #endregion - } -} diff --git a/ServiceHost/Session/OutputType.cs b/ServiceHost/Session/OutputType.cs deleted file mode 100644 index 8ba866d7..00000000 --- a/ServiceHost/Session/OutputType.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Enumerates the types of output lines that will be sent - /// to an IConsoleHost implementation. - /// - public enum OutputType - { - /// - /// A normal output line, usually written with the or Write-Host or - /// Write-Output cmdlets. - /// - Normal, - - /// - /// A debug output line, written with the Write-Debug cmdlet. - /// - Debug, - - /// - /// A verbose output line, written with the Write-Verbose cmdlet. - /// - Verbose, - - /// - /// A warning output line, written with the Write-Warning cmdlet. - /// - Warning, - - /// - /// An error output line, written with the Write-Error cmdlet or - /// as a result of some error during SqlTools pipeline execution. - /// - Error - } -} diff --git a/ServiceHost/Session/OutputWrittenEventArgs.cs b/ServiceHost/Session/OutputWrittenEventArgs.cs deleted file mode 100644 index 4b1dbbe3..00000000 --- a/ServiceHost/Session/OutputWrittenEventArgs.cs +++ /dev/null @@ -1,65 +0,0 @@ -// -// 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 -{ - /// - /// Provides details about output that has been written to the - /// SqlTools host. - /// - public class OutputWrittenEventArgs - { - /// - /// Gets the text of the output. - /// - public string OutputText { get; private set; } - - /// - /// Gets the type of the output. - /// - public OutputType OutputType { get; private set; } - - /// - /// Gets a boolean which indicates whether a newline - /// should be written after the output. - /// - public bool IncludeNewLine { get; private set; } - - /// - /// Gets the foreground color of the output text. - /// - public ConsoleColor ForegroundColor { get; private set; } - - /// - /// Gets the background color of the output text. - /// - public ConsoleColor BackgroundColor { get; private set; } - - /// - /// Creates an instance of the OutputWrittenEventArgs class. - /// - /// The text of the output. - /// A boolean which indicates whether a newline should be written after the output. - /// The type of the output. - /// The foreground color of the output text. - /// The background color of the output text. - public OutputWrittenEventArgs( - string outputText, - bool includeNewLine, - OutputType outputType, - ConsoleColor foregroundColor, - ConsoleColor backgroundColor) - { - this.OutputText = outputText; - this.IncludeNewLine = includeNewLine; - this.OutputType = outputType; - this.ForegroundColor = foregroundColor; - this.BackgroundColor = backgroundColor; - } - } -} - diff --git a/ServiceHost/Session/ProfilePaths.cs b/ServiceHost/Session/ProfilePaths.cs deleted file mode 100644 index 4af38521..00000000 --- a/ServiceHost/Session/ProfilePaths.cs +++ /dev/null @@ -1,109 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Microsoft.SqlTools.EditorServices.Session -{ - /// - /// Provides profile path resolution behavior relative to the name - /// of a particular SqlTools host. - /// - public class ProfilePaths - { - #region Constants - - /// - /// The file name for the "all hosts" profile. Also used as the - /// suffix for the host-specific profile filenames. - /// - public const string AllHostsProfileName = "profile.ps1"; - - #endregion - - #region Properties - - /// - /// Gets the profile path for all users, all hosts. - /// - public string AllUsersAllHosts { get; private set; } - - /// - /// Gets the profile path for all users, current host. - /// - public string AllUsersCurrentHost { get; private set; } - - /// - /// Gets the profile path for the current user, all hosts. - /// - public string CurrentUserAllHosts { get; private set; } - - /// - /// Gets the profile path for the current user and host. - /// - public string CurrentUserCurrentHost { get; private set; } - - #endregion - - #region Public Methods - - /// - /// Creates a new instance of the ProfilePaths class. - /// - /// - /// The identifier of the host used in the host-specific X_profile.ps1 filename. - /// - /// The base path to use for constructing AllUsers profile paths. - /// The base path to use for constructing CurrentUser profile paths. - public ProfilePaths( - string hostProfileId, - string baseAllUsersPath, - string baseCurrentUserPath) - { - this.Initialize(hostProfileId, baseAllUsersPath, baseCurrentUserPath); - } - - private void Initialize( - string hostProfileId, - string baseAllUsersPath, - string baseCurrentUserPath) - { - string currentHostProfileName = - string.Format( - "{0}_{1}", - hostProfileId, - AllHostsProfileName); - - this.AllUsersCurrentHost = Path.Combine(baseAllUsersPath, currentHostProfileName); - this.CurrentUserCurrentHost = Path.Combine(baseCurrentUserPath, currentHostProfileName); - this.AllUsersAllHosts = Path.Combine(baseAllUsersPath, AllHostsProfileName); - this.CurrentUserAllHosts = Path.Combine(baseCurrentUserPath, AllHostsProfileName); - } - - /// - /// Gets the list of profile paths that exist on the filesystem. - /// - /// An IEnumerable of profile path strings to be loaded. - public IEnumerable GetLoadableProfilePaths() - { - var profilePaths = - new string[] - { - this.AllUsersAllHosts, - this.AllUsersCurrentHost, - this.CurrentUserAllHosts, - this.CurrentUserCurrentHost - }; - - return profilePaths.Where(p => File.Exists(p)); - } - - #endregion - } -} - diff --git a/ServiceHost/Session/SqlToolsContext.cs b/ServiceHost/Session/SqlToolsContext.cs deleted file mode 100644 index d8016afd..00000000 --- a/ServiceHost/Session/SqlToolsContext.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// 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/Utility/AsyncContext.cs b/ServiceHost/Utility/AsyncContext.cs deleted file mode 100644 index c0baa889..00000000 --- a/ServiceHost/Utility/AsyncContext.cs +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Utility -{ - /// - /// Simplifies the setup of a SynchronizationContext for the use - /// of async calls in the current thread. - /// - public static class AsyncContext - { - /// - /// Starts a new ThreadSynchronizationContext, attaches it to - /// the thread, and then runs the given async main function. - /// - /// - /// The Task-returning Func which represents the "main" function - /// for the thread. - /// - public static void Start(Func asyncMainFunc) - { - // Is there already a synchronization context? - if (SynchronizationContext.Current != null) - { - throw new InvalidOperationException( - "A SynchronizationContext is already assigned on this thread."); - } - - // Create and register a synchronization context for this thread - var threadSyncContext = new ThreadSynchronizationContext(); - SynchronizationContext.SetSynchronizationContext(threadSyncContext); - - // Get the main task and act on its completion - Task asyncMainTask = asyncMainFunc(); - asyncMainTask.ContinueWith( - t => threadSyncContext.EndLoop(), - TaskScheduler.Default); - - // Start the synchronization context's request loop and - // wait for the main task to complete - threadSyncContext.RunLoopOnCurrentThread(); - asyncMainTask.GetAwaiter().GetResult(); - } - } -} - diff --git a/ServiceHost/Utility/AsyncContextThread.cs b/ServiceHost/Utility/AsyncContextThread.cs deleted file mode 100644 index 7b7947a5..00000000 --- a/ServiceHost/Utility/AsyncContextThread.cs +++ /dev/null @@ -1,85 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Utility -{ - /// - /// Provides a simplified interface for creating a new thread - /// and establishing an AsyncContext in it. - /// - public class AsyncContextThread - { - #region Private Fields - - private Task threadTask; - private string threadName; - private CancellationTokenSource threadCancellationToken = - new CancellationTokenSource(); - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the AsyncContextThread class. - /// - /// - /// The name of the thread for debugging purposes. - /// - public AsyncContextThread(string threadName) - { - this.threadName = threadName; - } - - #endregion - - #region Public Methods - - /// - /// Runs a task on the AsyncContextThread. - /// - /// - /// A Func which returns the task to be run on the thread. - /// - /// - /// A Task which can be used to monitor the thread for completion. - /// - public Task Run(Func taskReturningFunc) - { - // Start up a long-running task with the action as the - // main entry point for the thread - this.threadTask = - Task.Factory.StartNew( - () => - { - // Set the thread's name to help with debugging - Thread.CurrentThread.Name = "AsyncContextThread: " + this.threadName; - - // Set up an AsyncContext to run the task - AsyncContext.Start(taskReturningFunc); - }, - this.threadCancellationToken.Token, - TaskCreationOptions.LongRunning, - TaskScheduler.Default); - - return this.threadTask; - } - - /// - /// Stops the thread task. - /// - public void Stop() - { - this.threadCancellationToken.Cancel(); - } - - #endregion - } -} - diff --git a/ServiceHost/Utility/AsyncLock.cs b/ServiceHost/Utility/AsyncLock.cs deleted file mode 100644 index b12983ce..00000000 --- a/ServiceHost/Utility/AsyncLock.cs +++ /dev/null @@ -1,103 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Utility -{ - /// - /// Provides a simple wrapper over a SemaphoreSlim to allow - /// synchronization locking inside of async calls. Cannot be - /// used recursively. - /// - public class AsyncLock - { - #region Fields - - private Task lockReleaseTask; - private SemaphoreSlim lockSemaphore = new SemaphoreSlim(1, 1); - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the AsyncLock class. - /// - public AsyncLock() - { - this.lockReleaseTask = - Task.FromResult( - (IDisposable)new LockReleaser(this)); - } - - #endregion - - #region Public Methods - - /// - /// Locks - /// - /// A task which has an IDisposable - public Task LockAsync() - { - return this.LockAsync(CancellationToken.None); - } - - /// - /// Obtains or waits for a lock which can be used to synchronize - /// access to a resource. The wait may be cancelled with the - /// given CancellationToken. - /// - /// - /// A CancellationToken which can be used to cancel the lock. - /// - /// - public Task LockAsync(CancellationToken cancellationToken) - { - Task waitTask = lockSemaphore.WaitAsync(cancellationToken); - - return waitTask.IsCompleted ? - this.lockReleaseTask : - waitTask.ContinueWith( - (t, releaser) => - { - return (IDisposable)releaser; - }, - this.lockReleaseTask.Result, - cancellationToken, - TaskContinuationOptions.ExecuteSynchronously, - TaskScheduler.Default); - } - - #endregion - - #region Private Classes - - /// - /// Provides an IDisposable wrapper around an AsyncLock so - /// that it can easily be used inside of a 'using' block. - /// - private class LockReleaser : IDisposable - { - private AsyncLock lockToRelease; - - internal LockReleaser(AsyncLock lockToRelease) - { - this.lockToRelease = lockToRelease; - } - - public void Dispose() - { - this.lockToRelease.lockSemaphore.Release(); - } - } - - #endregion - } -} - diff --git a/ServiceHost/Utility/AsyncQueue.cs b/ServiceHost/Utility/AsyncQueue.cs deleted file mode 100644 index c899ee78..00000000 --- a/ServiceHost/Utility/AsyncQueue.cs +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.SqlTools.EditorServices.Utility -{ - /// - /// Provides a synchronized queue which can be used from within async - /// operations. This is primarily used for producer/consumer scenarios. - /// - /// The type of item contained in the queue. - public class AsyncQueue - { - #region Private Fields - - private AsyncLock queueLock = new AsyncLock(); - private Queue itemQueue; - private Queue> requestQueue; - - #endregion - - #region Properties - - /// - /// Returns true if the queue is currently empty. - /// - public bool IsEmpty { get; private set; } - - #endregion - - #region Constructors - - /// - /// Initializes an empty instance of the AsyncQueue class. - /// - public AsyncQueue() : this(Enumerable.Empty()) - { - } - - /// - /// Initializes an instance of the AsyncQueue class, pre-populated - /// with the given collection of items. - /// - /// - /// An IEnumerable containing the initial items with which the queue will - /// be populated. - /// - public AsyncQueue(IEnumerable initialItems) - { - this.itemQueue = new Queue(initialItems); - this.requestQueue = new Queue>(); - } - - #endregion - - #region Public Methods - - /// - /// Enqueues an item onto the end of the queue. - /// - /// The item to be added to the queue. - /// - /// A Task which can be awaited until the synchronized enqueue - /// operation completes. - /// - public async Task EnqueueAsync(T item) - { - using (await queueLock.LockAsync()) - { - TaskCompletionSource requestTaskSource = null; - - // Are any requests waiting? - while (this.requestQueue.Count > 0) - { - // Is the next request cancelled already? - requestTaskSource = this.requestQueue.Dequeue(); - if (!requestTaskSource.Task.IsCanceled) - { - // Dispatch the item - requestTaskSource.SetResult(item); - return; - } - } - - // No more requests waiting, queue the item for a later request - this.itemQueue.Enqueue(item); - this.IsEmpty = false; - } - } - - /// - /// Dequeues an item from the queue or waits asynchronously - /// until an item is available. - /// - /// - /// A Task which can be awaited until a value can be dequeued. - /// - public Task DequeueAsync() - { - return this.DequeueAsync(CancellationToken.None); - } - - /// - /// Dequeues an item from the queue or waits asynchronously - /// until an item is available. The wait can be cancelled - /// using the given CancellationToken. - /// - /// - /// A CancellationToken with which a dequeue wait can be cancelled. - /// - /// - /// A Task which can be awaited until a value can be dequeued. - /// - public async Task DequeueAsync(CancellationToken cancellationToken) - { - Task requestTask; - - using (await queueLock.LockAsync(cancellationToken)) - { - if (this.itemQueue.Count > 0) - { - // Items are waiting to be taken so take one immediately - T item = this.itemQueue.Dequeue(); - this.IsEmpty = this.itemQueue.Count == 0; - - return item; - } - else - { - // Queue the request for the next item - var requestTaskSource = new TaskCompletionSource(); - this.requestQueue.Enqueue(requestTaskSource); - - // Register the wait task for cancel notifications - cancellationToken.Register( - () => requestTaskSource.TrySetCanceled()); - - requestTask = requestTaskSource.Task; - } - } - - // Wait for the request task to complete outside of the lock - return await requestTask; - } - - #endregion - } -} - diff --git a/ServiceHost/Utility/Extensions.cs b/ServiceHost/Utility/Extensions.cs deleted file mode 100644 index c73bc03c..00000000 --- a/ServiceHost/Utility/Extensions.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// 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.Utility -{ - internal static class ObjectExtensions - { - /// - /// Extension to evaluate an object's ToString() method in an exception safe way. This will - /// extension method will not throw. - /// - /// The object on which to call ToString() - /// The ToString() return value or a suitable error message is that throws. - public static string SafeToString(this object obj) - { - string str; - - try - { - str = obj.ToString(); - } - catch (Exception ex) - { - str = $""; - } - - return str; - } - } -} diff --git a/ServiceHost/Utility/Logger.cs b/ServiceHost/Utility/Logger.cs deleted file mode 100644 index 6bdd39bd..00000000 --- a/ServiceHost/Utility/Logger.cs +++ /dev/null @@ -1,222 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; - -namespace Microsoft.SqlTools.EditorServices.Utility -{ - /// - /// Defines the level indicators for log messages. - /// - public enum LogLevel - { - /// - /// Indicates a verbose log message. - /// - Verbose, - - /// - /// Indicates a normal, non-verbose log message. - /// - Normal, - - /// - /// Indicates a warning message. - /// - Warning, - - /// - /// Indicates an error message. - /// - Error - } - - /// - /// Provides a simple logging interface. May be replaced with a - /// more robust solution at a later date. - /// - public static class Logger - { - private static LogWriter logWriter; - - /// - /// Initializes the Logger for the current session. - /// - /// - /// Optional. Specifies the path at which log messages will be written. - /// - /// - /// Optional. Specifies the minimum log message level to write to the log file. - /// - public static void Initialize( - string logFilePath = "SqlToolsService.log", - LogLevel minimumLogLevel = LogLevel.Normal) - { - if (logWriter != null) - { - logWriter.Dispose(); - } - - // TODO: Parameterize this - logWriter = - new LogWriter( - minimumLogLevel, - logFilePath, - true); - } - - /// - /// Closes the Logger. - /// - public static void Close() - { - if (logWriter != null) - { - logWriter.Dispose(); - } - } - - /// - /// Writes a message to the log file. - /// - /// The level at which the message will be written. - /// The message text to be written. - /// The name of the calling method. - /// The source file path where the calling method exists. - /// The line number of the calling method. - public static void Write( - LogLevel logLevel, - string logMessage, - [CallerMemberName] string callerName = null, - [CallerFilePath] string callerSourceFile = null, - [CallerLineNumber] int callerLineNumber = 0) - { - if (logWriter != null) - { - logWriter.Write( - logLevel, - logMessage, - callerName, - callerSourceFile, - callerLineNumber); - } - } - } - - internal class LogWriter : IDisposable - { - private TextWriter textWriter; - private LogLevel minimumLogLevel = LogLevel.Verbose; - - public LogWriter(LogLevel minimumLogLevel, string logFilePath, bool deleteExisting) - { - this.minimumLogLevel = minimumLogLevel; - - // Ensure that we have a usable log file path - if (!Path.IsPathRooted(logFilePath)) - { - logFilePath = - Path.Combine( - AppContext.BaseDirectory, - logFilePath); - } - - - if (!this.TryOpenLogFile(logFilePath, deleteExisting)) - { - // If the log file couldn't be opened at this location, - // try opening it in a more reliable path - this.TryOpenLogFile( - Path.Combine( - Environment.GetEnvironmentVariable("TEMP"), - Path.GetFileName(logFilePath)), - deleteExisting); - } - } - - public void Write( - LogLevel logLevel, - string logMessage, - string callerName = null, - string callerSourceFile = null, - int callerLineNumber = 0) - { - if (this.textWriter != null && - logLevel >= this.minimumLogLevel) - { - // Print the timestamp and log level - this.textWriter.WriteLine( - "{0} [{1}] - Method \"{2}\" at line {3} of {4}\r\n", - DateTime.Now, - logLevel.ToString().ToUpper(), - callerName, - callerLineNumber, - callerSourceFile); - - // Print out indented message lines - foreach (var messageLine in logMessage.Split('\n')) - { - this.textWriter.WriteLine(" " + messageLine.TrimEnd()); - } - - // Finish with a newline and flush the writer - this.textWriter.WriteLine(); - this.textWriter.Flush(); - } - } - - public void Dispose() - { - if (this.textWriter != null) - { - this.textWriter.Flush(); - this.textWriter.Dispose(); - this.textWriter = null; - } - } - - private bool TryOpenLogFile( - string logFilePath, - bool deleteExisting) - { - try - { - // Make sure the log directory exists - Directory.CreateDirectory( - Path.GetDirectoryName( - logFilePath)); - - // Open the log file for writing with UTF8 encoding - this.textWriter = - new StreamWriter( - new FileStream( - logFilePath, - deleteExisting ? - FileMode.Create : - FileMode.Append), - Encoding.UTF8); - - return true; - } - catch (Exception e) - { - if (e is UnauthorizedAccessException || - e is IOException) - { - // This exception is thrown when we can't open the file - // at the path in logFilePath. Return false to indicate - // that the log file couldn't be created. - return false; - } - - // Unexpected exception, rethrow it - throw; - } - } - } -} diff --git a/ServiceHost/Utility/ThreadSynchronizationContext.cs b/ServiceHost/Utility/ThreadSynchronizationContext.cs deleted file mode 100644 index 2389bbb0..00000000 --- a/ServiceHost/Utility/ThreadSynchronizationContext.cs +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections.Concurrent; -using System.Threading; - -namespace Microsoft.SqlTools.EditorServices.Utility -{ - /// - /// Provides a SynchronizationContext implementation that can be used - /// in console applications or any thread which doesn't have its - /// own SynchronizationContext. - /// - public class ThreadSynchronizationContext : SynchronizationContext - { - #region Private Fields - - private BlockingCollection> requestQueue = - new BlockingCollection>(); - - #endregion - - #region Constructors - - /// - /// Posts a request for execution to the SynchronizationContext. - /// This will be executed on the SynchronizationContext's thread. - /// - /// - /// The callback to be invoked on the SynchronizationContext's thread. - /// - /// - /// A state object to pass along to the callback when executed through - /// the SynchronizationContext. - /// - public override void Post(SendOrPostCallback callback, object state) - { - // Add the request to the queue - this.requestQueue.Add( - new Tuple( - callback, state)); - } - - #endregion - - #region Public Methods - - /// - /// Starts the SynchronizationContext message loop on the current thread. - /// - public void RunLoopOnCurrentThread() - { - Tuple request; - - while (this.requestQueue.TryTake(out request, Timeout.Infinite)) - { - // Invoke the request's callback - request.Item1(request.Item2); - } - } - - /// - /// Ends the SynchronizationContext message loop. - /// - public void EndLoop() - { - // Tell the blocking queue that we're done - this.requestQueue.CompleteAdding(); - } - - #endregion - } -} - diff --git a/ServiceHost/Utility/Validate.cs b/ServiceHost/Utility/Validate.cs deleted file mode 100644 index c788e67b..00000000 --- a/ServiceHost/Utility/Validate.cs +++ /dev/null @@ -1,143 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections.Generic; - -namespace Microsoft.SqlTools.EditorServices.Utility -{ - /// - /// Provides common validation methods to simplify method - /// parameter checks. - /// - public static class Validate - { - /// - /// Throws ArgumentNullException if value is null. - /// - /// The name of the parameter being validated. - /// The value of the parameter being validated. - public static void IsNotNull(string parameterName, object valueToCheck) - { - if (valueToCheck == null) - { - throw new ArgumentNullException(parameterName); - } - } - - /// - /// Throws ArgumentOutOfRangeException if the value is outside - /// of the given lower and upper limits. - /// - /// The name of the parameter being validated. - /// The value of the parameter being validated. - /// The lower limit which the value should not be less than. - /// The upper limit which the value should not be greater than. - public static void IsWithinRange( - string parameterName, - int valueToCheck, - int lowerLimit, - int upperLimit) - { - // TODO: Debug assert here if lowerLimit >= upperLimit - - if (valueToCheck < lowerLimit || valueToCheck > upperLimit) - { - throw new ArgumentOutOfRangeException( - parameterName, - valueToCheck, - string.Format( - "Value is not between {0} and {1}", - lowerLimit, - upperLimit)); - } - } - - /// - /// Throws ArgumentOutOfRangeException if the value is greater than or equal - /// to the given upper limit. - /// - /// The name of the parameter being validated. - /// The value of the parameter being validated. - /// The upper limit which the value should be less than. - public static void IsLessThan( - string parameterName, - int valueToCheck, - int upperLimit) - { - if (valueToCheck >= upperLimit) - { - throw new ArgumentOutOfRangeException( - parameterName, - valueToCheck, - string.Format( - "Value is greater than or equal to {0}", - upperLimit)); - } - } - - /// - /// Throws ArgumentOutOfRangeException if the value is less than or equal - /// to the given lower limit. - /// - /// The name of the parameter being validated. - /// The value of the parameter being validated. - /// The lower limit which the value should be greater than. - public static void IsGreaterThan( - string parameterName, - int valueToCheck, - int lowerLimit) - { - if (valueToCheck < lowerLimit) - { - throw new ArgumentOutOfRangeException( - parameterName, - valueToCheck, - string.Format( - "Value is less than or equal to {0}", - lowerLimit)); - } - } - - /// - /// Throws ArgumentException if the value is equal to the undesired value. - /// - /// The type of value to be validated. - /// The name of the parameter being validated. - /// The value that valueToCheck should not equal. - /// The value of the parameter being validated. - public static void IsNotEqual( - string parameterName, - TValue valueToCheck, - TValue undesiredValue) - { - if (EqualityComparer.Default.Equals(valueToCheck, undesiredValue)) - { - throw new ArgumentException( - string.Format( - "The given value '{0}' should not equal '{1}'", - valueToCheck, - undesiredValue), - parameterName); - } - } - - /// - /// Throws ArgumentException if the value is null, an empty string, - /// or a string containing only whitespace. - /// - /// The name of the parameter being validated. - /// The value of the parameter being validated. - public static void IsNotNullOrEmptyString(string parameterName, string valueToCheck) - { - if (string.IsNullOrWhiteSpace(valueToCheck)) - { - throw new ArgumentException( - "Parameter contains a null, empty, or whitespace string.", - parameterName); - } - } - } -} diff --git a/ServiceHost/Workspace/BufferPosition.cs b/ServiceHost/Workspace/BufferPosition.cs deleted file mode 100644 index 8f790d85..00000000 --- a/ServiceHost/Workspace/BufferPosition.cs +++ /dev/null @@ -1,110 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Diagnostics; - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Provides details about a position in a file buffer. All - /// positions are expressed in 1-based positions (i.e. the - /// first line and column in the file is position 1,1). - /// - [DebuggerDisplay("Position = {Line}:{Column}")] - public class BufferPosition - { - #region Properties - - /// - /// Provides an instance that represents a position that has not been set. - /// - public static readonly BufferPosition None = new BufferPosition(-1, -1); - - /// - /// Gets the line number of the position in the buffer. - /// - public int Line { get; private set; } - - /// - /// Gets the column number of the position in the buffer. - /// - public int Column { get; private set; } - - #endregion - - #region Constructors - - /// - /// Creates a new instance of the BufferPosition class. - /// - /// The line number of the position. - /// The column number of the position. - public BufferPosition(int line, int column) - { - this.Line = line; - this.Column = column; - } - - #endregion - - #region Public Methods - - /// - /// Compares two instances of the BufferPosition class. - /// - /// The object to which this instance will be compared. - /// True if the positions are equal, false otherwise. - public override bool Equals(object obj) - { - if (!(obj is BufferPosition)) - { - return false; - } - - BufferPosition other = (BufferPosition)obj; - - return - this.Line == other.Line && - this.Column == other.Column; - } - - /// - /// Calculates a unique hash code that represents this instance. - /// - /// A hash code representing this instance. - public override int GetHashCode() - { - return this.Line.GetHashCode() ^ this.Column.GetHashCode(); - } - - /// - /// Compares two positions to check if one is greater than the other. - /// - /// The first position to compare. - /// The second position to compare. - /// True if positionOne is greater than positionTwo. - public static bool operator >(BufferPosition positionOne, BufferPosition positionTwo) - { - return - (positionOne != null && positionTwo == null) || - (positionOne.Line > positionTwo.Line) || - (positionOne.Line == positionTwo.Line && - positionOne.Column > positionTwo.Column); - } - - /// - /// Compares two positions to check if one is less than the other. - /// - /// The first position to compare. - /// The second position to compare. - /// True if positionOne is less than positionTwo. - public static bool operator <(BufferPosition positionOne, BufferPosition positionTwo) - { - return positionTwo > positionOne; - } - - #endregion - } -} diff --git a/ServiceHost/Workspace/BufferRange.cs b/ServiceHost/Workspace/BufferRange.cs deleted file mode 100644 index 5d20598f..00000000 --- a/ServiceHost/Workspace/BufferRange.cs +++ /dev/null @@ -1,123 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Diagnostics; - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Provides details about a range between two positions in - /// a file buffer. - /// - [DebuggerDisplay("Start = {Start.Line}:{Start.Column}, End = {End.Line}:{End.Column}")] - public class BufferRange - { - #region Properties - - /// - /// Provides an instance that represents a range that has not been set. - /// - public static readonly BufferRange None = new BufferRange(0, 0, 0, 0); - - /// - /// Gets the start position of the range in the buffer. - /// - public BufferPosition Start { get; private set; } - - /// - /// Gets the end position of the range in the buffer. - /// - public BufferPosition End { get; private set; } - - /// - /// Returns true if the current range is non-zero, i.e. - /// contains valid start and end positions. - /// - public bool HasRange - { - get - { - return this.Equals(BufferRange.None); - } - } - - #endregion - - #region Constructors - - /// - /// Creates a new instance of the BufferRange class. - /// - /// The start position of the range. - /// The end position of the range. - public BufferRange(BufferPosition start, BufferPosition end) - { - if (start > end) - { - throw new ArgumentException( - string.Format( - "Start position ({0}, {1}) must come before or be equal to the end position ({2}, {3}).", - start.Line, start.Column, - end.Line, end.Column)); - } - - this.Start = start; - this.End = end; - } - - /// - /// Creates a new instance of the BufferRange class. - /// - /// The 1-based starting line number of the range. - /// The 1-based starting column number of the range. - /// The 1-based ending line number of the range. - /// The 1-based ending column number of the range. - public BufferRange( - int startLine, - int startColumn, - int endLine, - int endColumn) - { - this.Start = new BufferPosition(startLine, startColumn); - this.End = new BufferPosition(endLine, endColumn); - } - - #endregion - - #region Public Methods - - /// - /// Compares two instances of the BufferRange class. - /// - /// The object to which this instance will be compared. - /// True if the ranges are equal, false otherwise. - public override bool Equals(object obj) - { - if (!(obj is BufferRange)) - { - return false; - } - - BufferRange other = (BufferRange)obj; - - return - this.Start.Equals(other.Start) && - this.End.Equals(other.End); - } - - /// - /// Calculates a unique hash code that represents this instance. - /// - /// A hash code representing this instance. - public override int GetHashCode() - { - return this.Start.GetHashCode() ^ this.End.GetHashCode(); - } - - #endregion - } -} - diff --git a/ServiceHost/Workspace/FileChange.cs b/ServiceHost/Workspace/FileChange.cs deleted file mode 100644 index 2f6efdf8..00000000 --- a/ServiceHost/Workspace/FileChange.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Contains details relating to a content change in an open file. - /// - public class FileChange - { - /// - /// The string which is to be inserted in the file. - /// - public string InsertString { get; set; } - - /// - /// The 1-based line number where the change starts. - /// - public int Line { get; set; } - - /// - /// The 1-based column offset where the change starts. - /// - public int Offset { get; set; } - - /// - /// The 1-based line number where the change ends. - /// - public int EndLine { get; set; } - - /// - /// The 1-based column offset where the change ends. - /// - public int EndOffset { get; set; } - } -} diff --git a/ServiceHost/Workspace/FilePosition.cs b/ServiceHost/Workspace/FilePosition.cs deleted file mode 100644 index 2cb58745..00000000 --- a/ServiceHost/Workspace/FilePosition.cs +++ /dev/null @@ -1,110 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Provides details and operations for a buffer position in a - /// specific file. - /// - public class FilePosition : BufferPosition - { - #region Private Fields - - private ScriptFile scriptFile; - - #endregion - - #region Constructors - - /// - /// Creates a new FilePosition instance for the 1-based line and - /// column numbers in the specified file. - /// - /// The ScriptFile in which the position is located. - /// The 1-based line number in the file. - /// The 1-based column number in the file. - public FilePosition( - ScriptFile scriptFile, - int line, - int column) - : base(line, column) - { - this.scriptFile = scriptFile; - } - - /// - /// Creates a new FilePosition instance for the specified file by - /// copying the specified BufferPosition - /// - /// The ScriptFile in which the position is located. - /// The original BufferPosition from which the line and column will be copied. - public FilePosition( - ScriptFile scriptFile, - BufferPosition copiedPosition) - : this(scriptFile, copiedPosition.Line, copiedPosition.Column) - { - scriptFile.ValidatePosition(copiedPosition); - } - - #endregion - - #region Public Methods - - /// - /// Gets a FilePosition relative to this position by adding the - /// provided line and column offset relative to the contents of - /// the current file. - /// - /// The line offset to add to this position. - /// The column offset to add to this position. - /// A new FilePosition instance for the calculated position. - public FilePosition AddOffset(int lineOffset, int columnOffset) - { - return this.scriptFile.CalculatePosition( - this, - lineOffset, - columnOffset); - } - - /// - /// Gets a FilePosition for the line and column position - /// of the beginning of the current line after any initial - /// whitespace for indentation. - /// - /// A new FilePosition instance for the calculated position. - public FilePosition GetLineStart() - { - string scriptLine = scriptFile.FileLines[this.Line - 1]; - - int lineStartColumn = 1; - for (int i = 0; i < scriptLine.Length; i++) - { - if (!char.IsWhiteSpace(scriptLine[i])) - { - lineStartColumn = i + 1; - break; - } - } - - return new FilePosition(this.scriptFile, this.Line, lineStartColumn); - } - - /// - /// Gets a FilePosition for the line and column position - /// of the end of the current line. - /// - /// A new FilePosition instance for the calculated position. - public FilePosition GetLineEnd() - { - string scriptLine = scriptFile.FileLines[this.Line - 1]; - return new FilePosition(this.scriptFile, this.Line, scriptLine.Length + 1); - } - - #endregion - - } -} - diff --git a/ServiceHost/Workspace/ScriptFile.cs b/ServiceHost/Workspace/ScriptFile.cs deleted file mode 100644 index 90d66244..00000000 --- a/ServiceHost/Workspace/ScriptFile.cs +++ /dev/null @@ -1,538 +0,0 @@ -// -// 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.EditorServices.Utility; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Contains the details and contents of an open script file. - /// - public class ScriptFile - { - #region Private Fields - - private Version SqlToolsVersion; - - #endregion - - #region Properties - - /// - /// Gets a unique string that identifies this file. At this time, - /// this property returns a normalized version of the value stored - /// in the FilePath property. - /// - public string Id - { - get { return this.FilePath.ToLower(); } - } - - /// - /// Gets the path at which this file resides. - /// - public string FilePath { get; private set; } - - /// - /// Gets the path which the editor client uses to identify this file. - /// - public string ClientFilePath { get; private set; } - - /// - /// Gets or sets a boolean that determines whether - /// semantic analysis should be enabled for this file. - /// For internal use only. - /// - internal bool IsAnalysisEnabled { get; set; } - - /// - /// Gets a boolean that determines whether this file is - /// in-memory or not (either unsaved or non-file content). - /// - public bool IsInMemory { get; private set; } - - /// - /// Gets a string containing the full contents of the file. - /// - public string Contents - { - get - { - return string.Join("\r\n", this.FileLines); - } - } - - /// - /// Gets a BufferRange that represents the entire content - /// range of the file. - /// - public BufferRange FileRange { get; private set; } - - /// - /// Gets the list of syntax markers found by parsing this - /// file's contents. - /// - public ScriptFileMarker[] SyntaxMarkers - { - get; - private set; - } - - /// - /// Gets the list of strings for each line of the file. - /// - internal IList FileLines - { - get; - private set; - } - - /// - /// Gets the array of filepaths dot sourced in this ScriptFile - /// - public string[] ReferencedFiles - { - get; - private set; - } - - #endregion - - #region Constructors - - /// - /// Creates a new ScriptFile instance by reading file contents from - /// the given TextReader. - /// - /// The path at which the script file resides. - /// The path which the client uses to identify the file. - /// The TextReader to use for reading the file's contents. - /// The version of SqlTools for which the script is being parsed. - public ScriptFile( - string filePath, - string clientFilePath, - TextReader textReader, - Version SqlToolsVersion) - { - this.FilePath = filePath; - this.ClientFilePath = clientFilePath; - this.IsAnalysisEnabled = true; - this.IsInMemory = Workspace.IsPathInMemory(filePath); - this.SqlToolsVersion = SqlToolsVersion; - - this.SetFileContents(textReader.ReadToEnd()); - } - - /// - /// 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) - { - this.FilePath = filePath; - this.ClientFilePath = clientFilePath; - this.IsAnalysisEnabled = true; - this.SqlToolsVersion = SqlToolsVersion; - - this.SetFileContents(initialBuffer); - } - - #endregion - - #region Public Methods - - /// - /// Gets a line from the file's contents. - /// - /// The 1-based line number in the file. - /// The complete line at the given line number. - public string GetLine(int lineNumber) - { - Validate.IsWithinRange( - "lineNumber", lineNumber, - 1, this.FileLines.Count + 1); - - return this.FileLines[lineNumber - 1]; - } - - /// - /// Gets a range of lines from the file's contents. - /// - /// The buffer range from which lines will be extracted. - /// An array of strings from the specified range of the file. - public string[] GetLinesInRange(BufferRange bufferRange) - { - this.ValidatePosition(bufferRange.Start); - this.ValidatePosition(bufferRange.End); - - List linesInRange = new List(); - - int startLine = bufferRange.Start.Line, - endLine = bufferRange.End.Line; - - for (int line = startLine; line <= endLine; line++) - { - string currentLine = this.FileLines[line - 1]; - int startColumn = - line == startLine - ? bufferRange.Start.Column - : 1; - int endColumn = - line == endLine - ? bufferRange.End.Column - : currentLine.Length + 1; - - currentLine = - currentLine.Substring( - startColumn - 1, - endColumn - startColumn); - - linesInRange.Add(currentLine); - } - - return linesInRange.ToArray(); - } - - /// - /// Throws ArgumentOutOfRangeException if the given position is outside - /// of the file's buffer extents. - /// - /// The position in the buffer to be validated. - public void ValidatePosition(BufferPosition bufferPosition) - { - this.ValidatePosition( - bufferPosition.Line, - bufferPosition.Column); - } - - /// - /// Throws ArgumentOutOfRangeException if the given position is outside - /// of the file's buffer extents. - /// - /// The 1-based line to be validated. - /// The 1-based column to be validated. - public void ValidatePosition(int line, int column) - { - if (line < 1 || line > this.FileLines.Count + 1) - { - throw new ArgumentOutOfRangeException("Position is outside of file line range."); - } - - // The maximum column is either one past the length of the string - // or 1 if the string is empty. - string lineString = this.FileLines[line - 1]; - int maxColumn = lineString.Length > 0 ? lineString.Length + 1 : 1; - - if (column < 1 || column > maxColumn) - { - throw new ArgumentOutOfRangeException( - string.Format( - "Position is outside of column range for line {0}.", - line)); - } - } - - /// - /// Applies the provided FileChange to the file's contents - /// - /// The FileChange to apply to the file's contents. - public void ApplyChange(FileChange fileChange) - { - this.ValidatePosition(fileChange.Line, fileChange.Offset); - this.ValidatePosition(fileChange.EndLine, fileChange.EndOffset); - - // Break up the change lines - string[] changeLines = fileChange.InsertString.Split('\n'); - - // Get the first fragment of the first line - string firstLineFragment = - this.FileLines[fileChange.Line - 1] - .Substring(0, fileChange.Offset - 1); - - // Get the last fragment of the last line - string endLine = this.FileLines[fileChange.EndLine - 1]; - string lastLineFragment = - endLine.Substring( - fileChange.EndOffset - 1, - (this.FileLines[fileChange.EndLine - 1].Length - fileChange.EndOffset) + 1); - - // Remove the old lines - for (int i = 0; i <= fileChange.EndLine - fileChange.Line; i++) - { - this.FileLines.RemoveAt(fileChange.Line - 1); - } - - // Build and insert the new lines - int currentLineNumber = fileChange.Line; - for (int changeIndex = 0; changeIndex < changeLines.Length; changeIndex++) - { - // Since we split the lines above using \n, make sure to - // trim the ending \r's off as well. - string finalLine = changeLines[changeIndex].TrimEnd('\r'); - - // Should we add first or last line fragments? - if (changeIndex == 0) - { - // Append the first line fragment - finalLine = firstLineFragment + finalLine; - } - if (changeIndex == changeLines.Length - 1) - { - // Append the last line fragment - finalLine = finalLine + lastLineFragment; - } - - this.FileLines.Insert(currentLineNumber - 1, finalLine); - currentLineNumber++; - } - - // Parse the script again to be up-to-date - this.ParseFileContents(); - } - - /// - /// Calculates the zero-based character offset of a given - /// line and column position in the file. - /// - /// The 1-based line number from which the offset is calculated. - /// The 1-based column number from which the offset is calculated. - /// The zero-based offset for the given file position. - public int GetOffsetAtPosition(int lineNumber, int columnNumber) - { - Validate.IsWithinRange("lineNumber", lineNumber, 1, this.FileLines.Count); - Validate.IsGreaterThan("columnNumber", columnNumber, 0); - - int offset = 0; - - for(int i = 0; i < lineNumber; i++) - { - if (i == lineNumber - 1) - { - // Subtract 1 to account for 1-based column numbering - offset += columnNumber - 1; - } - else - { - // Add an offset to account for the current platform's newline characters - offset += this.FileLines[i].Length + Environment.NewLine.Length; - } - } - - return offset; - } - - /// - /// Calculates a FilePosition relative to a starting BufferPosition - /// using the given 1-based line and column offset. - /// - /// The original BufferPosition from which an new position should be calculated. - /// The 1-based line offset added to the original position in this file. - /// The 1-based column offset added to the original position in this file. - /// A new FilePosition instance with the resulting line and column number. - public FilePosition CalculatePosition( - BufferPosition originalPosition, - int lineOffset, - int columnOffset) - { - int newLine = originalPosition.Line + lineOffset, - newColumn = originalPosition.Column + columnOffset; - - this.ValidatePosition(newLine, newColumn); - - string scriptLine = this.FileLines[newLine - 1]; - newColumn = Math.Min(scriptLine.Length + 1, newColumn); - - return new FilePosition(this, newLine, newColumn); - } - - /// - /// Calculates the 1-based line and column number position based - /// on the given buffer offset. - /// - /// The buffer offset to convert. - /// A new BufferPosition containing the position of the offset. - public BufferPosition GetPositionAtOffset(int bufferOffset) - { - BufferRange bufferRange = - GetRangeBetweenOffsets( - bufferOffset, bufferOffset); - - return bufferRange.Start; - } - - /// - /// Calculates the 1-based line and column number range based on - /// the given start and end buffer offsets. - /// - /// The start offset of the range. - /// The end offset of the range. - /// A new BufferRange containing the positions in the offset range. - public BufferRange GetRangeBetweenOffsets(int startOffset, int endOffset) - { - bool foundStart = false; - int currentOffset = 0; - int searchedOffset = startOffset; - - BufferPosition startPosition = new BufferPosition(0, 0); - BufferPosition endPosition = startPosition; - - int line = 0; - while (line < this.FileLines.Count) - { - if (searchedOffset <= currentOffset + this.FileLines[line].Length) - { - int column = searchedOffset - currentOffset; - - // Have we already found the start position? - if (foundStart) - { - // Assign the end position and end the search - endPosition = new BufferPosition(line + 1, column + 1); - break; - } - else - { - startPosition = new BufferPosition(line + 1, column + 1); - - // Do we only need to find the start position? - if (startOffset == endOffset) - { - endPosition = startPosition; - break; - } - else - { - // Since the end offset can be on the same line, - // skip the line increment and continue searching - // for the end position - foundStart = true; - searchedOffset = endOffset; - continue; - } - } - } - - // Increase the current offset and include newline length - currentOffset += this.FileLines[line].Length + Environment.NewLine.Length; - line++; - } - - return new BufferRange(startPosition, endPosition); - } - - #endregion - - #region Private Methods - - private void SetFileContents(string fileContents) - { - // Split the file contents into lines and trim - // any carriage returns from the strings. - this.FileLines = - fileContents - .Split('\n') - .Select(line => line.TrimEnd('\r')) - .ToList(); - - // Parse the contents to get syntax tree and errors - this.ParseFileContents(); - } - - /// - /// Parses the current file contents to get the AST, tokens, - /// and parse errors. - /// - private void ParseFileContents() - { -#if false - ParseError[] parseErrors = null; - - // First, get the updated file range - int lineCount = this.FileLines.Count; - if (lineCount > 0) - { - this.FileRange = - new BufferRange( - new BufferPosition(1, 1), - new BufferPosition( - lineCount + 1, - this.FileLines[lineCount - 1].Length + 1)); - } - else - { - this.FileRange = BufferRange.None; - } - - try - { -#if SqlToolsv5r2 - // This overload appeared with Windows 10 Update 1 - if (this.SqlToolsVersion.Major >= 5 && - this.SqlToolsVersion.Build >= 10586) - { - // Include the file path so that module relative - // paths are evaluated correctly - this.ScriptAst = - Parser.ParseInput( - this.Contents, - this.FilePath, - out this.scriptTokens, - out parseErrors); - } - else - { - this.ScriptAst = - Parser.ParseInput( - this.Contents, - out this.scriptTokens, - out parseErrors); - } -#else - this.ScriptAst = - Parser.ParseInput( - this.Contents, - out this.scriptTokens, - out parseErrors); -#endif - } - catch (RuntimeException ex) - { - var parseError = - new ParseError( - null, - ex.ErrorRecord.FullyQualifiedErrorId, - ex.Message); - - parseErrors = new[] { parseError }; - this.scriptTokens = new Token[0]; - this.ScriptAst = null; - } - - // Translate parse errors into syntax markers - this.SyntaxMarkers = - parseErrors - .Select(ScriptFileMarker.FromParseError) - .ToArray(); - - //Get all dot sourced referenced files and store them - this.ReferencedFiles = - AstOperations.FindDotSourcedIncludes(this.ScriptAst); -#endif - } - -#endregion - } -} diff --git a/ServiceHost/Workspace/ScriptFileMarker.cs b/ServiceHost/Workspace/ScriptFileMarker.cs deleted file mode 100644 index 87c2576c..00000000 --- a/ServiceHost/Workspace/ScriptFileMarker.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Defines the message level of a script file marker. - /// - public enum ScriptFileMarkerLevel - { - /// - /// The marker represents an informational message. - /// - Information = 0, - - /// - /// The marker represents a warning message. - /// - Warning, - - /// - /// The marker represents an error message. - /// - Error - }; - - /// - /// Contains details about a marker that should be displayed - /// for the a script file. The marker information could come - /// from syntax parsing or semantic analysis of the script. - /// - public class ScriptFileMarker - { - #region Properties - - /// - /// Gets or sets the marker's message string. - /// - public string Message { get; set; } - - /// - /// Gets or sets the marker's message level. - /// - public ScriptFileMarkerLevel Level { get; set; } - - /// - /// Gets or sets the ScriptRegion where the marker should appear. - /// - public ScriptRegion ScriptRegion { get; set; } - - #endregion - } -} - diff --git a/ServiceHost/Workspace/ScriptRegion.cs b/ServiceHost/Workspace/ScriptRegion.cs deleted file mode 100644 index f2fa4ac8..00000000 --- a/ServiceHost/Workspace/ScriptRegion.cs +++ /dev/null @@ -1,89 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -//using System.Management.Automation.Language; - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Contains details about a specific region of text in script file. - /// - public sealed class ScriptRegion - { - #region Properties - - /// - /// Gets the file path of the script file in which this region is contained. - /// - public string File { get; set; } - - /// - /// Gets or sets the text that is contained within the region. - /// - public string Text { get; set; } - - /// - /// Gets or sets the starting line number of the region. - /// - public int StartLineNumber { get; set; } - - /// - /// Gets or sets the starting column number of the region. - /// - public int StartColumnNumber { get; set; } - - /// - /// Gets or sets the starting file offset of the region. - /// - public int StartOffset { get; set; } - - /// - /// Gets or sets the ending line number of the region. - /// - public int EndLineNumber { get; set; } - - /// - /// Gets or sets the ending column number of the region. - /// - public int EndColumnNumber { get; set; } - - /// - /// Gets or sets the ending file offset of the region. - /// - public int EndOffset { get; set; } - - #endregion - - #region Constructors - -#if false - /// - /// Creates a new instance of the ScriptRegion class from an - /// instance of an IScriptExtent implementation. - /// - /// - /// The IScriptExtent to copy into the ScriptRegion. - /// - /// - /// A new ScriptRegion instance with the same details as the IScriptExtent. - /// - public static ScriptRegion Create(IScriptExtent scriptExtent) - { - return new ScriptRegion - { - File = scriptExtent.File, - Text = scriptExtent.Text, - StartLineNumber = scriptExtent.StartLineNumber, - StartColumnNumber = scriptExtent.StartColumnNumber, - StartOffset = scriptExtent.StartOffset, - EndLineNumber = scriptExtent.EndLineNumber, - EndColumnNumber = scriptExtent.EndColumnNumber, - EndOffset = scriptExtent.EndOffset - }; - } -#endif - #endregion - } -} diff --git a/ServiceHost/Workspace/Workspace.cs b/ServiceHost/Workspace/Workspace.cs deleted file mode 100644 index 39e1d70f..00000000 --- a/ServiceHost/Workspace/Workspace.cs +++ /dev/null @@ -1,248 +0,0 @@ -// -// 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.EditorServices.Utility; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using System.Linq; - -namespace Microsoft.SqlTools.EditorServices -{ - /// - /// Manages a "workspace" of script files that are open for a particular - /// editing session. Also helps to navigate references between ScriptFiles. - /// - public class Workspace - { - #region Private Fields - - private Version SqlToolsVersion; - private Dictionary workspaceFiles = new Dictionary(); - - #endregion - - #region Properties - - /// - /// Gets or sets the root path of the workspace. - /// - public string WorkspacePath { get; set; } - - #endregion - - #region Constructors - - /// - /// Creates a new instance of the Workspace class. - /// - /// The version of SqlTools for which scripts will be parsed. - public Workspace(Version SqlToolsVersion) - { - this.SqlToolsVersion = SqlToolsVersion; - } - - #endregion - - #region Public Methods - - /// - /// Gets an open file in the workspace. If the file isn't open but - /// exists on the filesystem, load and return it. - /// - /// The file path at which the script resides. - /// - /// is not found. - /// - /// - /// contains a null or empty string. - /// - public ScriptFile GetFile(string filePath) - { - Validate.IsNotNullOrEmptyString("filePath", filePath); - - // Resolve the full file path - string resolvedFilePath = this.ResolveFilePath(filePath); - string keyName = resolvedFilePath.ToLower(); - - // Make sure the file isn't already loaded into the workspace - ScriptFile scriptFile = null; - if (!this.workspaceFiles.TryGetValue(keyName, out scriptFile)) - { - // This method allows FileNotFoundException to bubble up - // if the file isn't found. - using (FileStream fileStream = new FileStream(resolvedFilePath, FileMode.Open, FileAccess.Read)) - using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8)) - { - scriptFile = - new ScriptFile( - resolvedFilePath, - filePath, - streamReader, - this.SqlToolsVersion); - - this.workspaceFiles.Add(keyName, scriptFile); - } - - Logger.Write(LogLevel.Verbose, "Opened file on disk: " + resolvedFilePath); - } - - 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, @"`(?=[ \[\]])", ""); - } - - /// - /// Gets a new ScriptFile instance which is identified by the given file - /// path and initially contains the given buffer contents. - /// - /// - /// - /// - public ScriptFile GetFileBuffer(string filePath, string initialBuffer) - { - Validate.IsNotNullOrEmptyString("filePath", filePath); - - // Resolve the full file path - string resolvedFilePath = this.ResolveFilePath(filePath); - string keyName = resolvedFilePath.ToLower(); - - // Make sure the file isn't already loaded into the workspace - ScriptFile scriptFile = null; - if (!this.workspaceFiles.TryGetValue(keyName, out scriptFile)) - { - scriptFile = - new ScriptFile( - resolvedFilePath, - filePath, - initialBuffer, - this.SqlToolsVersion); - - this.workspaceFiles.Add(keyName, scriptFile); - - Logger.Write(LogLevel.Verbose, "Opened file as in-memory buffer: " + resolvedFilePath); - } - - return scriptFile; - } - - /// - /// Gets an array of all opened ScriptFiles in the workspace. - /// - /// An array of all opened ScriptFiles in the workspace. - public ScriptFile[] GetOpenedFiles() - { - return workspaceFiles.Values.ToArray(); - } - - /// - /// Closes a currently open script file with the given file path. - /// - /// The file path at which the script resides. - public void CloseFile(ScriptFile scriptFile) - { - Validate.IsNotNull("scriptFile", scriptFile); - - this.workspaceFiles.Remove(scriptFile.Id); - } - - private string GetBaseFilePath(string filePath) - { - if (IsPathInMemory(filePath)) - { - // If the file is in memory, use the workspace path - return this.WorkspacePath; - } - - if (!Path.IsPathRooted(filePath)) - { - // TODO: Assert instead? - throw new InvalidOperationException( - string.Format( - "Must provide a full path for originalScriptPath: {0}", - filePath)); - } - - // Get the directory of the file path - return Path.GetDirectoryName(filePath); - } - - private string ResolveRelativeScriptPath(string baseFilePath, string relativePath) - { - if (Path.IsPathRooted(relativePath)) - { - return relativePath; - } - - // Get the directory of the original script file, combine it - // with the given path and then resolve the absolute file path. - string combinedPath = - Path.GetFullPath( - Path.Combine( - baseFilePath, - relativePath)); - - return combinedPath; - } - - #endregion - } -} diff --git a/ServiceHost/project.json b/ServiceHost/project.json deleted file mode 100644 index 28565355..00000000 --- a/ServiceHost/project.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "version": "1.0.0-*", - "buildOptions": { - "debugType": "portable", - "emitEntryPoint": true - }, - "dependencies": { - "Newtonsoft.Json": "9.0.1", - }, - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.0" - } - }, - "imports": "dnxcore50" - } - } -}