forked from OSchip/llvm-project
1212 lines
40 KiB
C++
1212 lines
40 KiB
C++
//===--- Protocol.h - Language Server Protocol Implementation ---*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains structs based on the LSP specification at
|
|
// https://microsoft.github.io/language-server-protocol/specification
|
|
//
|
|
// This is not meant to be a complete implementation, new interfaces are added
|
|
// when they're needed.
|
|
//
|
|
// Each struct has a toJSON and fromJSON function, that converts between
|
|
// the struct and a JSON representation. (See JSON.h)
|
|
//
|
|
// Some structs also have operator<< serialization. This is for debugging and
|
|
// tests, and is not generally machine-readable.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LIB_MLIR_TOOLS_LSPSERVERSUPPORT_PROTOCOL_H_
|
|
#define LIB_MLIR_TOOLS_LSPSERVERSUPPORT_PROTOCOL_H_
|
|
|
|
#include "mlir/Support/LLVM.h"
|
|
#include "llvm/ADT/Optional.h"
|
|
#include "llvm/Support/JSON.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <bitset>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace mlir {
|
|
struct LogicalResult;
|
|
|
|
namespace lsp {
|
|
|
|
enum class ErrorCode {
|
|
// Defined by JSON RPC.
|
|
ParseError = -32700,
|
|
InvalidRequest = -32600,
|
|
MethodNotFound = -32601,
|
|
InvalidParams = -32602,
|
|
InternalError = -32603,
|
|
|
|
ServerNotInitialized = -32002,
|
|
UnknownErrorCode = -32001,
|
|
|
|
// Defined by the protocol.
|
|
RequestCancelled = -32800,
|
|
ContentModified = -32801,
|
|
};
|
|
|
|
/// Defines how the host (editor) should sync document changes to the language
|
|
/// server.
|
|
enum class TextDocumentSyncKind {
|
|
/// Documents should not be synced at all.
|
|
None = 0,
|
|
|
|
/// Documents are synced by always sending the full content of the document.
|
|
Full = 1,
|
|
|
|
/// Documents are synced by sending the full content on open. After that only
|
|
/// incremental updates to the document are sent.
|
|
Incremental = 2,
|
|
};
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// LSPError
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// This class models an LSP error as an llvm::Error.
|
|
class LSPError : public llvm::ErrorInfo<LSPError> {
|
|
public:
|
|
std::string message;
|
|
ErrorCode code;
|
|
static char ID;
|
|
|
|
LSPError(std::string message, ErrorCode code)
|
|
: message(std::move(message)), code(code) {}
|
|
|
|
void log(raw_ostream &os) const override {
|
|
os << int(code) << ": " << message;
|
|
}
|
|
std::error_code convertToErrorCode() const override {
|
|
return llvm::inconvertibleErrorCode();
|
|
}
|
|
};
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// URIForFile
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// URI in "file" scheme for a file.
|
|
class URIForFile {
|
|
public:
|
|
URIForFile() = default;
|
|
|
|
/// Try to build a URIForFile from the given URI string.
|
|
static llvm::Expected<URIForFile> fromURI(StringRef uri);
|
|
|
|
/// Try to build a URIForFile from the given absolute file path.
|
|
static llvm::Expected<URIForFile> fromFile(StringRef absoluteFilepath);
|
|
|
|
/// Returns the absolute path to the file.
|
|
StringRef file() const { return filePath; }
|
|
|
|
/// Returns the original uri of the file.
|
|
StringRef uri() const { return uriStr; }
|
|
|
|
explicit operator bool() const { return !filePath.empty(); }
|
|
|
|
friend bool operator==(const URIForFile &lhs, const URIForFile &rhs) {
|
|
return lhs.filePath == rhs.filePath;
|
|
}
|
|
friend bool operator!=(const URIForFile &lhs, const URIForFile &rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
friend bool operator<(const URIForFile &lhs, const URIForFile &rhs) {
|
|
return lhs.filePath < rhs.filePath;
|
|
}
|
|
|
|
private:
|
|
explicit URIForFile(std::string &&filePath, std::string &&uriStr)
|
|
: filePath(std::move(filePath)), uriStr(uriStr) {}
|
|
|
|
std::string filePath;
|
|
std::string uriStr;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const URIForFile &value);
|
|
bool fromJSON(const llvm::json::Value &value, URIForFile &result,
|
|
llvm::json::Path path);
|
|
raw_ostream &operator<<(raw_ostream &os, const URIForFile &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ClientCapabilities
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct ClientCapabilities {
|
|
/// Client supports hierarchical document symbols.
|
|
/// textDocument.documentSymbol.hierarchicalDocumentSymbolSupport
|
|
bool hierarchicalDocumentSymbol = false;
|
|
|
|
/// Client supports CodeAction return value for textDocument/codeAction.
|
|
/// textDocument.codeAction.codeActionLiteralSupport.
|
|
bool codeActionStructure = false;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, ClientCapabilities &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// InitializeParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
enum class TraceLevel {
|
|
Off = 0,
|
|
Messages = 1,
|
|
Verbose = 2,
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, TraceLevel &result,
|
|
llvm::json::Path path);
|
|
|
|
struct InitializeParams {
|
|
/// The capabilities provided by the client (editor or tool).
|
|
ClientCapabilities capabilities;
|
|
|
|
/// The initial trace setting. If omitted trace is disabled ('off').
|
|
Optional<TraceLevel> trace;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, InitializeParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// InitializedParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct NoParams {};
|
|
inline bool fromJSON(const llvm::json::Value &, NoParams &, llvm::json::Path) {
|
|
return true;
|
|
}
|
|
using InitializedParams = NoParams;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TextDocumentItem
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct TextDocumentItem {
|
|
/// The text document's URI.
|
|
URIForFile uri;
|
|
|
|
/// The text document's language identifier.
|
|
std::string languageId;
|
|
|
|
/// The content of the opened text document.
|
|
std::string text;
|
|
|
|
/// The version number of this document.
|
|
int64_t version;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, TextDocumentItem &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TextDocumentIdentifier
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct TextDocumentIdentifier {
|
|
/// The text document's URI.
|
|
URIForFile uri;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const TextDocumentIdentifier &value);
|
|
bool fromJSON(const llvm::json::Value &value, TextDocumentIdentifier &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// VersionedTextDocumentIdentifier
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct VersionedTextDocumentIdentifier {
|
|
/// The text document's URI.
|
|
URIForFile uri;
|
|
/// The version number of this document.
|
|
int64_t version;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &value);
|
|
bool fromJSON(const llvm::json::Value &value,
|
|
VersionedTextDocumentIdentifier &result, llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Position
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct Position {
|
|
Position(int line = 0, int character = 0)
|
|
: line(line), character(character) {}
|
|
|
|
/// Construct a position from the given source location.
|
|
Position(llvm::SourceMgr &mgr, SMLoc loc) {
|
|
std::pair<unsigned, unsigned> lineAndCol = mgr.getLineAndColumn(loc);
|
|
line = lineAndCol.first - 1;
|
|
character = lineAndCol.second - 1;
|
|
}
|
|
|
|
/// Line position in a document (zero-based).
|
|
int line = 0;
|
|
|
|
/// Character offset on a line in a document (zero-based).
|
|
int character = 0;
|
|
|
|
friend bool operator==(const Position &lhs, const Position &rhs) {
|
|
return std::tie(lhs.line, lhs.character) ==
|
|
std::tie(rhs.line, rhs.character);
|
|
}
|
|
friend bool operator!=(const Position &lhs, const Position &rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
friend bool operator<(const Position &lhs, const Position &rhs) {
|
|
return std::tie(lhs.line, lhs.character) <
|
|
std::tie(rhs.line, rhs.character);
|
|
}
|
|
friend bool operator<=(const Position &lhs, const Position &rhs) {
|
|
return std::tie(lhs.line, lhs.character) <=
|
|
std::tie(rhs.line, rhs.character);
|
|
}
|
|
|
|
/// Convert this position into a source location in the main file of the given
|
|
/// source manager.
|
|
SMLoc getAsSMLoc(llvm::SourceMgr &mgr) const {
|
|
return mgr.FindLocForLineAndColumn(mgr.getMainFileID(), line + 1,
|
|
character + 1);
|
|
}
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, Position &result,
|
|
llvm::json::Path path);
|
|
llvm::json::Value toJSON(const Position &value);
|
|
raw_ostream &operator<<(raw_ostream &os, const Position &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Range
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct Range {
|
|
Range() = default;
|
|
Range(Position start, Position end) : start(start), end(end) {}
|
|
Range(Position loc) : Range(loc, loc) {}
|
|
|
|
/// Construct a range from the given source range.
|
|
Range(llvm::SourceMgr &mgr, SMRange range)
|
|
: Range(Position(mgr, range.Start), Position(mgr, range.End)) {}
|
|
|
|
/// The range's start position.
|
|
Position start;
|
|
|
|
/// The range's end position.
|
|
Position end;
|
|
|
|
friend bool operator==(const Range &lhs, const Range &rhs) {
|
|
return std::tie(lhs.start, lhs.end) == std::tie(rhs.start, rhs.end);
|
|
}
|
|
friend bool operator!=(const Range &lhs, const Range &rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
friend bool operator<(const Range &lhs, const Range &rhs) {
|
|
return std::tie(lhs.start, lhs.end) < std::tie(rhs.start, rhs.end);
|
|
}
|
|
|
|
bool contains(Position pos) const { return start <= pos && pos < end; }
|
|
bool contains(Range range) const {
|
|
return start <= range.start && range.end <= end;
|
|
}
|
|
|
|
/// Convert this range into a source range in the main file of the given
|
|
/// source manager.
|
|
SMRange getAsSMRange(llvm::SourceMgr &mgr) const {
|
|
SMLoc startLoc = start.getAsSMLoc(mgr);
|
|
SMLoc endLoc = end.getAsSMLoc(mgr);
|
|
// Check that the start and end locations are valid.
|
|
if (!startLoc.isValid() || !endLoc.isValid() ||
|
|
startLoc.getPointer() > endLoc.getPointer())
|
|
return SMRange();
|
|
return SMRange(startLoc, endLoc);
|
|
}
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, Range &result,
|
|
llvm::json::Path path);
|
|
llvm::json::Value toJSON(const Range &value);
|
|
raw_ostream &operator<<(raw_ostream &os, const Range &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Location
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct Location {
|
|
Location() = default;
|
|
Location(const URIForFile &uri, Range range) : uri(uri), range(range) {}
|
|
|
|
/// Construct a Location from the given source range.
|
|
Location(const URIForFile &uri, llvm::SourceMgr &mgr, SMRange range)
|
|
: Location(uri, Range(mgr, range)) {}
|
|
|
|
/// The text document's URI.
|
|
URIForFile uri;
|
|
Range range;
|
|
|
|
friend bool operator==(const Location &lhs, const Location &rhs) {
|
|
return lhs.uri == rhs.uri && lhs.range == rhs.range;
|
|
}
|
|
|
|
friend bool operator!=(const Location &lhs, const Location &rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
friend bool operator<(const Location &lhs, const Location &rhs) {
|
|
return std::tie(lhs.uri, lhs.range) < std::tie(rhs.uri, rhs.range);
|
|
}
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, Location &result,
|
|
llvm::json::Path path);
|
|
llvm::json::Value toJSON(const Location &value);
|
|
raw_ostream &operator<<(raw_ostream &os, const Location &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TextDocumentPositionParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct TextDocumentPositionParams {
|
|
/// The text document.
|
|
TextDocumentIdentifier textDocument;
|
|
|
|
/// The position inside the text document.
|
|
Position position;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value,
|
|
TextDocumentPositionParams &result, llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ReferenceParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct ReferenceContext {
|
|
/// Include the declaration of the current symbol.
|
|
bool includeDeclaration = false;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, ReferenceContext &result,
|
|
llvm::json::Path path);
|
|
|
|
struct ReferenceParams : public TextDocumentPositionParams {
|
|
ReferenceContext context;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, ReferenceParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DidOpenTextDocumentParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct DidOpenTextDocumentParams {
|
|
/// The document that was opened.
|
|
TextDocumentItem textDocument;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, DidOpenTextDocumentParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DidCloseTextDocumentParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct DidCloseTextDocumentParams {
|
|
/// The document that was closed.
|
|
TextDocumentIdentifier textDocument;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value,
|
|
DidCloseTextDocumentParams &result, llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DidChangeTextDocumentParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct TextDocumentContentChangeEvent {
|
|
/// Try to apply this change to the given contents string.
|
|
LogicalResult applyTo(std::string &contents) const;
|
|
/// Try to apply a set of changes to the given contents string.
|
|
static LogicalResult applyTo(ArrayRef<TextDocumentContentChangeEvent> changes,
|
|
std::string &contents);
|
|
|
|
/// The range of the document that changed.
|
|
Optional<Range> range;
|
|
|
|
/// The length of the range that got replaced.
|
|
Optional<int> rangeLength;
|
|
|
|
/// The new text of the range/document.
|
|
std::string text;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value,
|
|
TextDocumentContentChangeEvent &result, llvm::json::Path path);
|
|
|
|
struct DidChangeTextDocumentParams {
|
|
/// The document that changed.
|
|
VersionedTextDocumentIdentifier textDocument;
|
|
|
|
/// The actual content changes.
|
|
std::vector<TextDocumentContentChangeEvent> contentChanges;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value,
|
|
DidChangeTextDocumentParams &result, llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// MarkupContent
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Describes the content type that a client supports in various result literals
|
|
/// like `Hover`.
|
|
enum class MarkupKind {
|
|
PlainText,
|
|
Markdown,
|
|
};
|
|
raw_ostream &operator<<(raw_ostream &os, MarkupKind kind);
|
|
|
|
struct MarkupContent {
|
|
MarkupKind kind = MarkupKind::PlainText;
|
|
std::string value;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const MarkupContent &mc);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Hover
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct Hover {
|
|
/// Construct a default hover with the given range that uses Markdown content.
|
|
Hover(Range range) : contents{MarkupKind::Markdown, ""}, range(range) {}
|
|
|
|
/// The hover's content.
|
|
MarkupContent contents;
|
|
|
|
/// An optional range is a range inside a text document that is used to
|
|
/// visualize a hover, e.g. by changing the background color.
|
|
Optional<Range> range;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const Hover &hover);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// SymbolKind
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
enum class 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,
|
|
Object = 19,
|
|
Key = 20,
|
|
Null = 21,
|
|
EnumMember = 22,
|
|
Struct = 23,
|
|
Event = 24,
|
|
Operator = 25,
|
|
TypeParameter = 26
|
|
};
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DocumentSymbol
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Represents programming constructs like variables, classes, interfaces etc.
|
|
/// that appear in a document. Document symbols can be hierarchical and they
|
|
/// have two ranges: one that encloses its definition and one that points to its
|
|
/// most interesting range, e.g. the range of an identifier.
|
|
struct DocumentSymbol {
|
|
DocumentSymbol() = default;
|
|
DocumentSymbol(DocumentSymbol &&) = default;
|
|
DocumentSymbol(const Twine &name, SymbolKind kind, Range range,
|
|
Range selectionRange)
|
|
: name(name.str()), kind(kind), range(range),
|
|
selectionRange(selectionRange) {}
|
|
|
|
/// The name of this symbol.
|
|
std::string name;
|
|
|
|
/// More detail for this symbol, e.g the signature of a function.
|
|
std::string detail;
|
|
|
|
/// The kind of this symbol.
|
|
SymbolKind kind;
|
|
|
|
/// The range enclosing this symbol not including leading/trailing whitespace
|
|
/// but everything else like comments. This information is typically used to
|
|
/// determine if the clients cursor is inside the symbol to reveal in the
|
|
/// symbol in the UI.
|
|
Range range;
|
|
|
|
/// The range that should be selected and revealed when this symbol is being
|
|
/// picked, e.g the name of a function. Must be contained by the `range`.
|
|
Range selectionRange;
|
|
|
|
/// Children of this symbol, e.g. properties of a class.
|
|
std::vector<DocumentSymbol> children;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const DocumentSymbol &symbol);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DocumentSymbolParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct DocumentSymbolParams {
|
|
// The text document to find symbols in.
|
|
TextDocumentIdentifier textDocument;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, DocumentSymbolParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DiagnosticRelatedInformation
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Represents a related message and source code location for a diagnostic.
|
|
/// This should be used to point to code locations that cause or related to a
|
|
/// diagnostics, e.g. when duplicating a symbol in a scope.
|
|
struct DiagnosticRelatedInformation {
|
|
DiagnosticRelatedInformation() = default;
|
|
DiagnosticRelatedInformation(Location location, std::string message)
|
|
: location(std::move(location)), message(std::move(message)) {}
|
|
|
|
/// The location of this related diagnostic information.
|
|
Location location;
|
|
/// The message of this related diagnostic information.
|
|
std::string message;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value,
|
|
DiagnosticRelatedInformation &result, llvm::json::Path path);
|
|
llvm::json::Value toJSON(const DiagnosticRelatedInformation &info);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Diagnostic
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
enum class DiagnosticSeverity {
|
|
/// It is up to the client to interpret diagnostics as error, warning, info or
|
|
/// hint.
|
|
Undetermined = 0,
|
|
Error = 1,
|
|
Warning = 2,
|
|
Information = 3,
|
|
Hint = 4
|
|
};
|
|
|
|
struct Diagnostic {
|
|
/// The source range where the message applies.
|
|
Range range;
|
|
|
|
/// The diagnostic's severity. Can be omitted. If omitted it is up to the
|
|
/// client to interpret diagnostics as error, warning, info or hint.
|
|
DiagnosticSeverity severity = DiagnosticSeverity::Undetermined;
|
|
|
|
/// A human-readable string describing the source of this diagnostic, e.g.
|
|
/// 'typescript' or 'super lint'.
|
|
std::string source;
|
|
|
|
/// The diagnostic's message.
|
|
std::string message;
|
|
|
|
/// An array of related diagnostic information, e.g. when symbol-names within
|
|
/// a scope collide all definitions can be marked via this property.
|
|
Optional<std::vector<DiagnosticRelatedInformation>> relatedInformation;
|
|
|
|
/// The diagnostic's category. Can be omitted.
|
|
/// An LSP extension that's used to send the name of the category over to the
|
|
/// client. The category typically describes the compilation stage during
|
|
/// which the issue was produced, e.g. "Semantic Issue" or "Parse Issue".
|
|
Optional<std::string> category;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const Diagnostic &diag);
|
|
bool fromJSON(const llvm::json::Value &value, Diagnostic &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// PublishDiagnosticsParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct PublishDiagnosticsParams {
|
|
PublishDiagnosticsParams(URIForFile uri, int64_t version)
|
|
: uri(std::move(uri)), version(version) {}
|
|
|
|
/// The URI for which diagnostic information is reported.
|
|
URIForFile uri;
|
|
/// The list of reported diagnostics.
|
|
std::vector<Diagnostic> diagnostics;
|
|
/// The version number of the document the diagnostics are published for.
|
|
int64_t version;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const PublishDiagnosticsParams ¶ms);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TextEdit
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct TextEdit {
|
|
/// The range of the text document to be manipulated. To insert
|
|
/// text into a document create a range where start === end.
|
|
Range range;
|
|
|
|
/// The string to be inserted. For delete operations use an
|
|
/// empty string.
|
|
std::string newText;
|
|
};
|
|
|
|
inline bool operator==(const TextEdit &lhs, const TextEdit &rhs) {
|
|
return std::tie(lhs.newText, lhs.range) == std::tie(rhs.newText, rhs.range);
|
|
}
|
|
|
|
bool fromJSON(const llvm::json::Value &value, TextEdit &result,
|
|
llvm::json::Path path);
|
|
llvm::json::Value toJSON(const TextEdit &value);
|
|
raw_ostream &operator<<(raw_ostream &os, const TextEdit &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CompletionItemKind
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// The kind of a completion entry.
|
|
enum class CompletionItemKind {
|
|
Missing = 0,
|
|
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,
|
|
Folder = 19,
|
|
EnumMember = 20,
|
|
Constant = 21,
|
|
Struct = 22,
|
|
Event = 23,
|
|
Operator = 24,
|
|
TypeParameter = 25,
|
|
};
|
|
bool fromJSON(const llvm::json::Value &value, CompletionItemKind &result,
|
|
llvm::json::Path path);
|
|
|
|
constexpr auto kCompletionItemKindMin =
|
|
static_cast<size_t>(CompletionItemKind::Text);
|
|
constexpr auto kCompletionItemKindMax =
|
|
static_cast<size_t>(CompletionItemKind::TypeParameter);
|
|
using CompletionItemKindBitset = std::bitset<kCompletionItemKindMax + 1>;
|
|
bool fromJSON(const llvm::json::Value &value, CompletionItemKindBitset &result,
|
|
llvm::json::Path path);
|
|
|
|
CompletionItemKind
|
|
adjustKindToCapability(CompletionItemKind kind,
|
|
CompletionItemKindBitset &supportedCompletionItemKinds);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CompletionItem
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Defines whether the insert text in a completion item should be interpreted
|
|
/// as plain text or a snippet.
|
|
enum class InsertTextFormat {
|
|
Missing = 0,
|
|
/// The primary text to be inserted is treated as a plain string.
|
|
PlainText = 1,
|
|
/// The primary text to be inserted is treated as a snippet.
|
|
///
|
|
/// A snippet can define tab stops and placeholders with `$1`, `$2`
|
|
/// and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end
|
|
/// of the snippet. Placeholders with equal identifiers are linked, that is
|
|
/// typing in one will update others too.
|
|
///
|
|
/// See also:
|
|
/// https//github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
|
|
Snippet = 2,
|
|
};
|
|
|
|
struct CompletionItem {
|
|
CompletionItem() = default;
|
|
CompletionItem(const Twine &label, CompletionItemKind kind,
|
|
StringRef sortText = "")
|
|
: label(label.str()), kind(kind), sortText(sortText.str()),
|
|
insertTextFormat(InsertTextFormat::PlainText) {}
|
|
|
|
/// The label of this completion item. By default also the text that is
|
|
/// inserted when selecting this completion.
|
|
std::string label;
|
|
|
|
/// The kind of this completion item. Based of the kind an icon is chosen by
|
|
/// the editor.
|
|
CompletionItemKind kind = CompletionItemKind::Missing;
|
|
|
|
/// A human-readable string with additional information about this item, like
|
|
/// type or symbol information.
|
|
std::string detail;
|
|
|
|
/// A human-readable string that represents a doc-comment.
|
|
Optional<MarkupContent> documentation;
|
|
|
|
/// A string that should be used when comparing this item with other items.
|
|
/// When `falsy` the label is used.
|
|
std::string sortText;
|
|
|
|
/// A string that should be used when filtering a set of completion items.
|
|
/// When `falsy` the label is used.
|
|
std::string filterText;
|
|
|
|
/// A string that should be inserted to a document when selecting this
|
|
/// completion. When `falsy` the label is used.
|
|
std::string insertText;
|
|
|
|
/// The format of the insert text. The format applies to both the `insertText`
|
|
/// property and the `newText` property of a provided `textEdit`.
|
|
InsertTextFormat insertTextFormat = InsertTextFormat::Missing;
|
|
|
|
/// An edit which is applied to a document when selecting this completion.
|
|
/// When an edit is provided `insertText` is ignored.
|
|
///
|
|
/// Note: The range of the edit must be a single line range and it must
|
|
/// contain the position at which completion has been requested.
|
|
Optional<TextEdit> textEdit;
|
|
|
|
/// An optional array of additional text edits that are applied when selecting
|
|
/// this completion. Edits must not overlap with the main edit nor with
|
|
/// themselves.
|
|
std::vector<TextEdit> additionalTextEdits;
|
|
|
|
/// Indicates if this item is deprecated.
|
|
bool deprecated = false;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const CompletionItem &value);
|
|
raw_ostream &operator<<(raw_ostream &os, const CompletionItem &value);
|
|
bool operator<(const CompletionItem &lhs, const CompletionItem &rhs);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CompletionList
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Represents a collection of completion items to be presented in the editor.
|
|
struct CompletionList {
|
|
/// The list is not complete. Further typing should result in recomputing the
|
|
/// list.
|
|
bool isIncomplete = false;
|
|
|
|
/// The completion items.
|
|
std::vector<CompletionItem> items;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const CompletionList &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CompletionContext
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
enum class CompletionTriggerKind {
|
|
/// Completion was triggered by typing an identifier (24x7 code
|
|
/// complete), manual invocation (e.g Ctrl+Space) or via API.
|
|
Invoked = 1,
|
|
|
|
/// Completion was triggered by a trigger character specified by
|
|
/// the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
|
|
TriggerCharacter = 2,
|
|
|
|
/// Completion was re-triggered as the current completion list is incomplete.
|
|
TriggerTriggerForIncompleteCompletions = 3
|
|
};
|
|
|
|
struct CompletionContext {
|
|
/// How the completion was triggered.
|
|
CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked;
|
|
|
|
/// The trigger character (a single character) that has trigger code complete.
|
|
/// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
|
|
std::string triggerCharacter;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, CompletionContext &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CompletionParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct CompletionParams : TextDocumentPositionParams {
|
|
CompletionContext context;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, CompletionParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ParameterInformation
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// A single parameter of a particular signature.
|
|
struct ParameterInformation {
|
|
/// The label of this parameter. Ignored when labelOffsets is set.
|
|
std::string labelString;
|
|
|
|
/// Inclusive start and exclusive end offsets withing the containing signature
|
|
/// label.
|
|
Optional<std::pair<unsigned, unsigned>> labelOffsets;
|
|
|
|
/// The documentation of this parameter. Optional.
|
|
std::string documentation;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const ParameterInformation &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// SignatureInformation
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Represents the signature of something callable.
|
|
struct SignatureInformation {
|
|
/// The label of this signature. Mandatory.
|
|
std::string label;
|
|
|
|
/// The documentation of this signature. Optional.
|
|
std::string documentation;
|
|
|
|
/// The parameters of this signature.
|
|
std::vector<ParameterInformation> parameters;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const SignatureInformation &value);
|
|
raw_ostream &operator<<(raw_ostream &os, const SignatureInformation &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// SignatureHelp
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Represents the signature of a callable.
|
|
struct SignatureHelp {
|
|
/// The resulting signatures.
|
|
std::vector<SignatureInformation> signatures;
|
|
|
|
/// The active signature.
|
|
int activeSignature = 0;
|
|
|
|
/// The active parameter of the active signature.
|
|
int activeParameter = 0;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const SignatureHelp &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DocumentLinkParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Parameters for the document link request.
|
|
struct DocumentLinkParams {
|
|
/// The document to provide document links for.
|
|
TextDocumentIdentifier textDocument;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, DocumentLinkParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DocumentLink
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// A range in a text document that links to an internal or external resource,
|
|
/// like another text document or a web site.
|
|
struct DocumentLink {
|
|
DocumentLink() = default;
|
|
DocumentLink(Range range, URIForFile target)
|
|
: range(range), target(std::move(target)) {}
|
|
|
|
/// The range this link applies to.
|
|
Range range;
|
|
|
|
/// The uri this link points to. If missing a resolve request is sent later.
|
|
URIForFile target;
|
|
|
|
// TODO: The following optional fields defined by the language server protocol
|
|
// are unsupported:
|
|
//
|
|
// data?: any - A data entry field that is preserved on a document link
|
|
// between a DocumentLinkRequest and a
|
|
// DocumentLinkResolveRequest.
|
|
|
|
friend bool operator==(const DocumentLink &lhs, const DocumentLink &rhs) {
|
|
return lhs.range == rhs.range && lhs.target == rhs.target;
|
|
}
|
|
|
|
friend bool operator!=(const DocumentLink &lhs, const DocumentLink &rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const DocumentLink &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// InlayHintsParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// A parameter literal used in inlay hint requests.
|
|
struct InlayHintsParams {
|
|
/// The text document.
|
|
TextDocumentIdentifier textDocument;
|
|
|
|
/// The visible document range for which inlay hints should be computed.
|
|
Range range;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, InlayHintsParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// InlayHintKind
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Inlay hint kinds.
|
|
enum class InlayHintKind {
|
|
/// An inlay hint that for a type annotation.
|
|
///
|
|
/// An example of a type hint is a hint in this position:
|
|
/// auto var ^ = expr;
|
|
/// which shows the deduced type of the variable.
|
|
Type = 1,
|
|
|
|
/// An inlay hint that is for a parameter.
|
|
///
|
|
/// An example of a parameter hint is a hint in this position:
|
|
/// func(^arg);
|
|
/// which shows the name of the corresponding parameter.
|
|
Parameter = 2,
|
|
};
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// InlayHint
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Inlay hint information.
|
|
struct InlayHint {
|
|
InlayHint(InlayHintKind kind, Position pos) : position(pos), kind(kind) {}
|
|
|
|
/// The position of this hint.
|
|
Position position;
|
|
|
|
/// The label of this hint. A human readable string or an array of
|
|
/// InlayHintLabelPart label parts.
|
|
///
|
|
/// *Note* that neither the string nor the label part can be empty.
|
|
std::string label;
|
|
|
|
/// The kind of this hint. Can be omitted in which case the client should fall
|
|
/// back to a reasonable default.
|
|
InlayHintKind kind;
|
|
|
|
/// Render padding before the hint.
|
|
///
|
|
/// Note: Padding should use the editor's background color, not the
|
|
/// background color of the hint itself. That means padding can be used
|
|
/// to visually align/separate an inlay hint.
|
|
bool paddingLeft = false;
|
|
|
|
/// Render padding after the hint.
|
|
///
|
|
/// Note: Padding should use the editor's background color, not the
|
|
/// background color of the hint itself. That means padding can be used
|
|
/// to visually align/separate an inlay hint.
|
|
bool paddingRight = false;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const InlayHint &);
|
|
bool operator==(const InlayHint &lhs, const InlayHint &rhs);
|
|
bool operator<(const InlayHint &lhs, const InlayHint &rhs);
|
|
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, InlayHintKind value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CodeActionContext
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct CodeActionContext {
|
|
/// An array of diagnostics known on the client side overlapping the range
|
|
/// provided to the `textDocument/codeAction` request. They are provided so
|
|
/// that the server knows which errors are currently presented to the user for
|
|
/// the given range. There is no guarantee that these accurately reflect the
|
|
/// error state of the resource. The primary parameter to compute code actions
|
|
/// is the provided range.
|
|
std::vector<Diagnostic> diagnostics;
|
|
|
|
/// Requested kind of actions to return.
|
|
///
|
|
/// Actions not of this kind are filtered out by the client before being
|
|
/// shown. So servers can omit computing them.
|
|
std::vector<std::string> only;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, CodeActionContext &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CodeActionParams
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct CodeActionParams {
|
|
/// The document in which the command was invoked.
|
|
TextDocumentIdentifier textDocument;
|
|
|
|
/// The range for which the command was invoked.
|
|
Range range;
|
|
|
|
/// Context carrying additional information.
|
|
CodeActionContext context;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, CodeActionParams &result,
|
|
llvm::json::Path path);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// WorkspaceEdit
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
struct WorkspaceEdit {
|
|
/// Holds changes to existing resources.
|
|
std::map<std::string, std::vector<TextEdit>> changes;
|
|
|
|
/// Note: "documentChanges" is not currently used because currently there is
|
|
/// no support for versioned edits.
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
bool fromJSON(const llvm::json::Value &value, WorkspaceEdit &result,
|
|
llvm::json::Path path);
|
|
llvm::json::Value toJSON(const WorkspaceEdit &value);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CodeAction
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// A code action represents a change that can be performed in code, e.g. to fix
|
|
/// a problem or to refactor code.
|
|
///
|
|
/// A CodeAction must set either `edit` and/or a `command`. If both are
|
|
/// supplied, the `edit` is applied first, then the `command` is executed.
|
|
struct CodeAction {
|
|
/// A short, human-readable, title for this code action.
|
|
std::string title;
|
|
|
|
/// The kind of the code action.
|
|
/// Used to filter code actions.
|
|
Optional<std::string> kind;
|
|
const static llvm::StringLiteral kQuickFix;
|
|
const static llvm::StringLiteral kRefactor;
|
|
const static llvm::StringLiteral kInfo;
|
|
|
|
/// The diagnostics that this code action resolves.
|
|
Optional<std::vector<Diagnostic>> diagnostics;
|
|
|
|
/// Marks this as a preferred action. Preferred actions are used by the
|
|
/// `auto fix` command and can be targeted by keybindings.
|
|
/// A quick fix should be marked preferred if it properly addresses the
|
|
/// underlying error. A refactoring should be marked preferred if it is the
|
|
/// most reasonable choice of actions to take.
|
|
bool isPreferred = false;
|
|
|
|
/// The workspace edit this code action performs.
|
|
Optional<WorkspaceEdit> edit;
|
|
};
|
|
|
|
/// Add support for JSON serialization.
|
|
llvm::json::Value toJSON(const CodeAction &);
|
|
|
|
} // namespace lsp
|
|
} // namespace mlir
|
|
|
|
namespace llvm {
|
|
template <>
|
|
struct format_provider<mlir::lsp::Position> {
|
|
static void format(const mlir::lsp::Position &pos, raw_ostream &os,
|
|
StringRef style) {
|
|
assert(style.empty() && "style modifiers for this type are not supported");
|
|
os << pos;
|
|
}
|
|
};
|
|
} // namespace llvm
|
|
|
|
#endif
|