Skip to content

Update the struct definitions to match version 3.14 of the LSP spec #202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 6, 2019
Merged
94 changes: 75 additions & 19 deletions Sources/LanguageServerProtocol/ClientCapabilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,23 @@ public struct TextDocumentClientCapabilities: Hashable, Codable {

/// Capabilities specific to `SignatureInformation`.
public struct SignatureInformation: Hashable, Codable {
public struct ParameterInformation: Hashable, Codable {
/// The client supports processing label offsets instead of a simple label string.
var labelOffsetSupport: Bool? = nil

public init(labelOffsetSupport: Bool? = nil) {
self.labelOffsetSupport = labelOffsetSupport
}
}

/// Documentation formats supported by the client from most to least preferred.
public var signatureInformation: [MarkupKind]? = nil
public var documentationFormat: [MarkupKind]? = nil

public var parameterInformation: ParameterInformation? = nil

public init(signatureInformation: [MarkupKind]? = nil) {
self.signatureInformation = signatureInformation
public init(signatureInformation: [MarkupKind]? = nil, parameterInformation: ParameterInformation? = nil) {
self.documentationFormat = signatureInformation
self.parameterInformation = parameterInformation
}
}

Expand Down Expand Up @@ -276,6 +288,19 @@ public struct TextDocumentClientCapabilities: Hashable, Codable {
}
}

public struct DynamicRegistrationLinkSupportCapability: Hashable, Codable {
/// Whether the client supports dynamic registaration of this request.
public var dynamicRegistration: Bool? = nil

/// The client supports additional metadata in the form of declaration links.
public var linkSupport: Bool? = nil

public init(dynamicRegistration: Bool? = nil, linkSupport: Bool?) {
self.dynamicRegistration = dynamicRegistration
self.linkSupport = linkSupport
}
}

/// Capabilities specific to the `textDocument/codeAction` request.
public struct CodeAction: Hashable, Codable {

Expand All @@ -294,24 +319,38 @@ public struct TextDocumentClientCapabilities: Hashable, Codable {
}
}

/// Whether the client supports dynamic registaration of this request.
public var dynamicRegistration: Bool? = nil

public var codeActionKind: CodeActionKind

public init(dynamicRegistration: Bool? = nil, codeActionKind: CodeActionKind) {
self.dynamicRegistration = dynamicRegistration
public init(codeActionKind: CodeActionKind) {
self.codeActionKind = codeActionKind
}
}

/// Whether the client supports dynamic registaration of this request.
public var dynamicRegistration: Bool?

public var codeActionLiteralSupport: CodeActionLiteralSupport? = nil

public init(codeActionLiteralSupport: CodeActionLiteralSupport? = nil) {
public init(dynamicRegistration: Bool? = nil, codeActionLiteralSupport: CodeActionLiteralSupport? = nil) {
self.codeActionLiteralSupport = codeActionLiteralSupport
}
}

/// Capabilities specific to `textDocument/rename`.
public struct Rename: Hashable, Codable {

/// Whether the client supports dynamic registaration of this request.
public var dynamicRegistration: Bool?

/// The client supports testing for validity of rename operations before execution.
public var prepareSupport: Bool?

public init(dynamicRegistration: Bool? = nil, prepareSupport: Bool? = nil) {
self.dynamicRegistration = dynamicRegistration
self.prepareSupport = prepareSupport
}
}

/// Capabilities specific to `textDocument/publishDiagnostics`.
public struct PublishDiagnostics: Hashable, Codable {
/// Whether the client accepts diagnostics with related information.
Expand Down Expand Up @@ -364,11 +403,13 @@ public struct TextDocumentClientCapabilities: Hashable, Codable {

public var onTypeFormatting: DynamicRegistrationCapability? = nil

public var definition: DynamicRegistrationCapability? = nil
public var declaration: DynamicRegistrationLinkSupportCapability? = nil

public var definition: DynamicRegistrationLinkSupportCapability? = nil

public var typeDefinition: DynamicRegistrationCapability? = nil
public var typeDefinition: DynamicRegistrationLinkSupportCapability? = nil

public var implementation: DynamicRegistrationCapability? = nil
public var implementation: DynamicRegistrationLinkSupportCapability? = nil

public var codeAction: CodeAction? = nil

Expand All @@ -384,13 +425,27 @@ public struct TextDocumentClientCapabilities: Hashable, Codable {

public var foldingRange: FoldingRange? = nil

public init(synchronization: Synchronization? = nil, completion: Completion? = nil, hover: Hover? = nil,
signatureHelp: SignatureHelp? = nil, references: DynamicRegistrationCapability? = nil, documentHighlight: DynamicRegistrationCapability? = nil,
documentSymbol: DocumentSymbol? = nil, formatting: DynamicRegistrationCapability? = nil, rangeFormatting: DynamicRegistrationCapability? = nil,
onTypeFormatting: DynamicRegistrationCapability? = nil, definition: DynamicRegistrationCapability? = nil, typeDefinition: DynamicRegistrationCapability? = nil,
implementation: DynamicRegistrationCapability? = nil, codeAction: CodeAction? = nil, codeLens: DynamicRegistrationCapability? = nil,
documentLink: DynamicRegistrationCapability? = nil, colorProvider: DynamicRegistrationCapability? = nil, rename: DynamicRegistrationCapability? = nil,
publishDiagnostics: PublishDiagnostics? = nil, foldingRange: FoldingRange? = nil) {
public init(synchronization: Synchronization? = nil,
completion: Completion? = nil,
hover: Hover? = nil,
signatureHelp: SignatureHelp? = nil,
references: DynamicRegistrationCapability? = nil,
documentHighlight: DynamicRegistrationCapability? = nil,
documentSymbol: DocumentSymbol? = nil,
formatting: DynamicRegistrationCapability? = nil,
rangeFormatting: DynamicRegistrationCapability? = nil,
onTypeFormatting: DynamicRegistrationCapability? = nil,
declaration: DynamicRegistrationLinkSupportCapability? = nil,
definition: DynamicRegistrationLinkSupportCapability? = nil,
typeDefinition: DynamicRegistrationLinkSupportCapability? = nil,
implementation: DynamicRegistrationLinkSupportCapability? = nil,
codeAction: CodeAction? = nil,
codeLens: DynamicRegistrationCapability? = nil,
documentLink: DynamicRegistrationCapability? = nil,
colorProvider: DynamicRegistrationCapability? = nil,
rename: DynamicRegistrationCapability? = nil,
publishDiagnostics: PublishDiagnostics? = nil,
foldingRange: FoldingRange? = nil) {
self.synchronization = synchronization
self.completion = completion
self.hover = hover
Expand All @@ -401,6 +456,7 @@ public struct TextDocumentClientCapabilities: Hashable, Codable {
self.formatting = formatting
self.rangeFormatting = rangeFormatting
self.onTypeFormatting = onTypeFormatting
self.declaration = declaration
self.definition = definition
self.typeDefinition = typeDefinition
self.implementation = implementation
Expand Down
53 changes: 52 additions & 1 deletion Sources/LanguageServerProtocol/Completion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,45 @@ public struct CompletionRequest: TextDocumentRequest, Hashable {

public var position: Position

// public var context: CompletionContext?
public var context: CompletionContext?

public init(textDocument: TextDocumentIdentifier, position: Position) {
self.textDocument = textDocument
self.position = position
}
}

/// How a completion was triggered
public struct CompletionTriggerKind: RawRepresentable, Codable, Hashable {
/// Completion was triggered by typing an identifier (24x7 code complete), manual invocation (e.g Ctrl+Space) or via API.
public static let invoked = CompletionTriggerKind(rawValue: 1)

/// Completion was triggered by a trigger character specified by the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
public static let triggerCharacter = CompletionTriggerKind(rawValue: 2)

/// Completion was re-triggered as the current completion list is incomplete.
public static let triggerFromIncompleteCompletions = CompletionTriggerKind(rawValue: 3)

public let rawValue: Int
public init(rawValue: Int) {
self.rawValue = rawValue
}
}

/// Contains additional information about the context in which a completion request is triggered.
public struct CompletionContext: Codable, Hashable {
/// How the completion was triggered.
public var triggerKind: CompletionTriggerKind

/// The trigger character (a single character) that has trigger code complete. Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
public var triggerCharacter: String?

public init(triggerKind: CompletionTriggerKind, triggerCharacter: String? = nil) {
self.triggerKind = triggerKind
self.triggerCharacter = triggerCharacter
}
}

/// List of completion items. If this list has been filtered already, the `isIncomplete` flag
/// indicates that the client should re-query code-completions if the filter text changes.
public struct CompletionList: ResponseType, Hashable {
Expand All @@ -56,4 +87,24 @@ public struct CompletionList: ResponseType, Hashable {
self.isIncomplete = isIncomplete
self.items = items
}

public init(from decoder: Decoder) throws {
// Try decoding as CompletionList
do {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.isIncomplete = try container.decode(Bool.self, forKey: .isIncomplete)
self.items = try container.decode([CompletionItem].self, forKey: .items)
return
} catch {}

// Try decoding as [CompletionItem]
do {
self.items = try [CompletionItem](from: decoder)
self.isIncomplete = false
return
} catch {}

let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected CompletionList or [CompletionItem]")
throw DecodingError.dataCorrupted(context)
}
}
41 changes: 35 additions & 6 deletions Sources/LanguageServerProtocol/CompletionItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ public struct CompletionItem: Codable, Hashable {
/// The display name of the completion.
public var label: String

/// The kind of completion item - e.g. method, property.
public var kind: CompletionItemKind

/// An extended human-readable name (longer than `label`, but simpler than `documentation`).
public var detail: String?

/// A human-readable string that represents a doc-comment.
public var documentation: CompletionItemDocumentation?

/// The name to use for sorting the result. If `nil`, use `label.
public var sortText: String?

Expand All @@ -40,23 +46,19 @@ public struct CompletionItem: Codable, Hashable {
/// The format of the `textEdit.nextText` or `insertText` value.
public var insertTextFormat: InsertTextFormat?

/// The kind of completion item - e.g. method, property.
public var kind: CompletionItemKind

/// Whether the completion is for a deprecated symbol.
public var deprecated: Bool?

// TODO: remaining members

public init(
label: String,
kind: CompletionItemKind,
detail: String? = nil,
documentation: CompletionItemDocumentation? = nil,
sortText: String? = nil,
filterText: String? = nil,
textEdit: TextEdit? = nil,
insertText: String? = nil,
insertTextFormat: InsertTextFormat? = nil,
kind: CompletionItemKind,
deprecated: Bool? = nil)
{
self.label = label
Expand All @@ -80,3 +82,30 @@ public enum InsertTextFormat: Int, Codable, Hashable {
/// The text to insert is a "snippet", which may contain placeholders.
case snippet = 2
}

public enum CompletionItemDocumentation: Hashable {
case string(String)
case markupContent(MarkupContent)
}

extension CompletionItemDocumentation: Codable {
public init(from decoder: Decoder) throws {
if let string = try? String(from: decoder) {
self = .string(string)
} else if let markupContent = try? MarkupContent(from: decoder) {
self = .markupContent(markupContent)
} else {
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected String or MarkupContent")
throw DecodingError.dataCorrupted(context)
}
}

public func encode(to encoder: Encoder) throws {
switch self {
case .string(let string):
try string.encode(to: encoder)
case .markupContent(let markupContent):
try markupContent.encode(to: encoder)
}
}
}
2 changes: 1 addition & 1 deletion Sources/LanguageServerProtocol/DefinitionRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
/// - Returns: The location of the definition(s).
public struct DefinitionRequest: TextDocumentRequest, Hashable {
public static let method: String = "textDocument/definition"
public typealias Response = [Location]
public typealias Response = LocationsOrLocationLinksResponse?

/// The document in which to lookup the symbol location.
public var textDocument: TextDocumentIdentifier
Expand Down
33 changes: 29 additions & 4 deletions Sources/LanguageServerProtocol/DocumentSymbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
/// - Returns: An array of document symbols, if any.
public struct DocumentSymbolRequest: TextDocumentRequest, Hashable {
public static let method: String = "textDocument/documentSymbol"
public typealias Response = [DocumentSymbol]?
public typealias Response = DocumentSymbolResponse?

/// The document in which to lookup the symbol location.
public var textDocument: TextDocumentIdentifier
Expand All @@ -34,6 +34,31 @@ public struct DocumentSymbolRequest: TextDocumentRequest, Hashable {
}
}

public enum DocumentSymbolResponse: ResponseType, Hashable {
case documentSymbols([DocumentSymbol])
case symbolInformation([SymbolInformation])

public init(from decoder: Decoder) throws {
if let documentSymbols = try? [DocumentSymbol](from: decoder) {
self = .documentSymbols(documentSymbols)
} else if let symbolInformation = try? [SymbolInformation](from: decoder) {
self = .symbolInformation(symbolInformation)
} else {
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected [DocumentSymbol] or [SymbolInformation]")
throw DecodingError.dataCorrupted(context)
}
}

public func encode(to encoder: Encoder) throws {
switch self {
case .documentSymbols(let documentSymbols):
try documentSymbols.encode(to: encoder)
case .symbolInformation(let symbolInformation):
try symbolInformation.encode(to: encoder)
}
}
}

/// 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.
Expand Down Expand Up @@ -70,12 +95,12 @@ public struct DocumentSymbol: Hashable, Codable, ResponseType {

public init(
name: String,
detail: String?,
detail: String? = nil,
kind: SymbolKind,
deprecated: Bool?,
deprecated: Bool? = nil,
range: Range<Position>,
selectionRange: Range<Position>,
children: [DocumentSymbol]?)
children: [DocumentSymbol]? = nil)
{
self.name = name
self.detail = detail
Expand Down
4 changes: 2 additions & 2 deletions Sources/LanguageServerProtocol/Hover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extension MarkedString: Codable {
} else if let codeBlock = try? MarkdownCodeBlock(from: decoder) {
self = .codeBlock(language: codeBlock.language, value: codeBlock.value)
} else {
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "MarkedString is neither pure string nor code block")
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected String or MarkdownCodeBlock")
throw DecodingError.dataCorrupted(context)
}
}
Expand All @@ -104,7 +104,7 @@ extension HoverResponseContents: Codable {
} else if let value = try? MarkupContent(from: decoder) {
self = .markupContent(value)
} else {
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "HoverResponseContents is neither MarkedString, nor [MarkedString], nor MarkupContent")
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected MarkedString, [MarkedString], or MarkupContent")
throw DecodingError.dataCorrupted(context)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/LanguageServerProtocol/ImplementationRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/// protocol conforming types, subclasses, or overrides.
public struct ImplementationRequest: TextDocumentRequest, Hashable {
public static let method: String = "textDocument/implementation"
public typealias Response = [Location]
public typealias Response = LocationsOrLocationLinksResponse?

/// The document in which the given symbol is located.
public var textDocument: TextDocumentIdentifier
Expand Down
Loading