TSQL Formatter Service (#229)

- TSqlFormatterService with support for formatting document and text range inside document
- Settings support for all formatting options.
- Extensibility support so that the service can be initialized using MEF extensibility, and can find all necessary TSqlFormatters using the same process

Fix Initialize request error on startup
- Messages were being read from the input channel before all request handlers were registered
- In particular, the Initialize request which is key for any server to talk to the client was getting lost because the message reader thread begins consuming, and we take an extra few hundred milliseconds due to MEF startup before we register the handler
- The solution is to initialize the message handler so request handlers can register, but not actually start processing incoming messages until all handers are ready. This is a safer way to go and should improve reliability overall

Improvements from internal prototype:
- Normalizing baselines to handle the line ending differences on Mac & Linux vs. Windows
- Significantly shortened most lines by implementing base class methods to wrap common objects from Visitor.Context and removing unnecessary "this." syntax
- Refactored the SqlCommonTableExpressionFormatter and related classes to reduce code count significantly. This provides a pattern to follow when refactoring other classes for similar clarity. It's likely a lot of common logic could be found and reused across these.
- Reduced overall code size by adding utility methods
This commit is contained in:
Kevin Cunnane
2017-02-14 23:40:17 -08:00
committed by GitHub
parent eb4f2f2b91
commit 7477642854
212 changed files with 7905 additions and 184 deletions

View File

@@ -0,0 +1,113 @@
//
// 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.ServiceLayer.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.Formatter.Contracts
{
/// <summary>
/// A formatting request to process an entire document
/// </summary>
public class DocumentFormattingRequest
{
public static readonly
RequestType<DocumentFormattingParams, TextEdit[]> Type =
RequestType<DocumentFormattingParams, TextEdit[]>.Create("textDocument/formatting");
}
/// <summary>
/// A formatting request to process a specific range inside a document
/// </summary>
public class DocumentRangeFormattingRequest
{
public static readonly
RequestType<DocumentRangeFormattingParams, TextEdit[]> Type =
RequestType<DocumentRangeFormattingParams, TextEdit[]>.Create("textDocument/rangeFormatting");
}
/// <summary>
/// A formatting request to handle a user typing, giving a chance to update the text based on this
/// </summary>
public class DocumentOnTypeFormattingRequest
{
public static readonly
RequestType<DocumentOnTypeFormattingParams, TextEdit[]> Type =
RequestType<DocumentOnTypeFormattingParams, TextEdit[]>.Create("textDocument/onTypeFormatting");
}
/// <summary>
/// Params for the <see cref="DocumentFormattingRequest"/>
/// </summary>
public class DocumentFormattingParams
{
/// <summary>
/// The document to format.
/// </summary>
public TextDocumentIdentifier TextDocument { get; set; }
/// <summary>
/// The formatting options
/// </summary>
public FormattingOptions Options { get; set; }
}
/// <summary>
/// Params for the <see cref="DocumentRangeFormattingRequest"/>
/// </summary>
public class DocumentRangeFormattingParams : DocumentFormattingParams
{
/// <summary>
/// The range to format
/// </summary>
public Range Range { get; set; }
}
/// <summary>
/// Params for the <see cref="DocumentOnTypeFormattingRequest"/>
/// </summary>
public class DocumentOnTypeFormattingParams : DocumentFormattingParams
{
/// <summary>
/// The position at which this request was sent.
/// </summary>
Position Position { get; set; }
/// <summary>
/// The character that has been typed.
/// </summary>
string Ch { get; set; }
}
/// <summary>
/// Value-object describing what options formatting should use.
/// </summary>
public class FormattingOptions
{
/// <summary>
/// Size of a tab in spaces
/// </summary>
public int TabSize { get; set; }
/// <summary>
/// Prefer spaces over tabs.
/// </summary>
public bool InsertSpaces { get; set; }
// TODO there may be other options passed by VSCode - format is
// [key: string]: boolean | number | string;
// Determine how these might be passed and add them here
}
}