Skip to content

Provide Data Types in Document Outline; Provide Code Documentation in CompletionItem #422

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 1 commit into from
Aug 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public struct CompletionItem: Codable, Hashable {
{
self.label = label
self.detail = detail
self.documentation = documentation
self.sortText = sortText
self.filterText = filterText
self.textEdit = textEdit
Expand Down
2 changes: 2 additions & 0 deletions Sources/SourceKitLSP/Swift/CodeCompletion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ extension SwiftLanguageServer {
var filterName: String? = value[self.keys.name]
let insertText: String? = value[self.keys.sourcetext]
let typeName: String? = value[self.keys.typename]
let docBrief: String? = value[self.keys.doc_brief]

let clientCompletionCapabilities = self.clientCapabilities.textDocument?.completion
let clientSupportsSnippets = clientCompletionCapabilities?.completionItem?.snippetSupport == true
Expand Down Expand Up @@ -173,6 +174,7 @@ extension SwiftLanguageServer {
label: name,
kind: kind?.asCompletionItemKind(self.values) ?? .value,
detail: typeName,
documentation: docBrief != nil ? .markupContent(MarkupContent(kind: .markdown, value: docBrief!)) : nil,
sortText: nil,
filterText: filterName,
textEdit: textEdit,
Expand Down
2 changes: 1 addition & 1 deletion Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ extension SwiftLanguageServer {
children = nil
}
return DocumentSymbol(name: name,
detail: nil,
detail: value[self.keys.typename] as String?,
kind: kind,
deprecated: nil,
range: range,
Expand Down
10 changes: 5 additions & 5 deletions Tests/SourceKitLSPTests/DocumentSymbolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ func initialize(capabilities: DocumentSymbolCapabilities) {
),
DocumentSymbol(
name: "computedVariable",
detail: nil,
detail: "Int",
kind: .variable,
deprecated: nil,
range: range(from: (10, 0), to: (10, 38)),
Expand Down Expand Up @@ -540,7 +540,7 @@ func initialize(capabilities: DocumentSymbolCapabilities) {
),
DocumentSymbol(
name: "computedProperty",
detail: nil,
detail: "Int",
kind: .property,
deprecated: nil,
range: range(from: (21, 2), to: (21, 40)),
Expand Down Expand Up @@ -576,7 +576,7 @@ func initialize(capabilities: DocumentSymbolCapabilities) {
),
DocumentSymbol(
name: "staticComputedProperty",
detail: nil,
detail: "Int",
kind: .property,
deprecated: nil,
range: range(from: (25, 2), to: (25, 53)),
Expand All @@ -585,7 +585,7 @@ func initialize(capabilities: DocumentSymbolCapabilities) {
),
DocumentSymbol(
name: "classProperty",
detail: nil,
detail: "Int",
kind: .property,
deprecated: nil,
range: range(from: (26, 2), to: (26, 43)),
Expand Down Expand Up @@ -620,7 +620,7 @@ func initialize(capabilities: DocumentSymbolCapabilities) {
),
DocumentSymbol(
name: "localComputedVariable",
detail: nil,
detail: "Int",
kind: .variable,
deprecated: nil,
range: range(from: (30, 4), to: (30, 47)),
Expand Down
25 changes: 14 additions & 11 deletions Tests/SourceKitLSPTests/SwiftCompletionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ final class SwiftCompletionTests: XCTestCase {
/// Base document text to use for completion tests.
let text: String = """
struct S {
/// Documentation for `abc`.
var abc: Int

func test(a: Int) {
Expand Down Expand Up @@ -103,7 +104,7 @@ final class SwiftCompletionTests: XCTestCase {

let selfDot = try! sk.sendSync(CompletionRequest(
textDocument: TextDocumentIdentifier(url),
position: Position(line: 4, utf16index: 9)))
position: Position(line: 5, utf16index: 9)))

XCTAssertEqual(selfDot.isIncomplete, options.serverSideFiltering)
XCTAssertGreaterThanOrEqual(selfDot.items.count, 2)
Expand All @@ -112,16 +113,17 @@ final class SwiftCompletionTests: XCTestCase {
if let abc = abc {
XCTAssertEqual(abc.kind, .property)
XCTAssertEqual(abc.detail, "Int")
XCTAssertEqual(abc.documentation, .markupContent(MarkupContent(kind: .markdown, value: "Documentation for abc.")))
XCTAssertEqual(abc.filterText, "abc")
XCTAssertEqual(abc.textEdit, TextEdit(range: Position(line: 4, utf16index: 9)..<Position(line: 4, utf16index: 9), newText: "abc"))
XCTAssertEqual(abc.textEdit, TextEdit(range: Position(line: 5, utf16index: 9)..<Position(line: 5, utf16index: 9), newText: "abc"))
XCTAssertEqual(abc.insertText, "abc")
XCTAssertEqual(abc.insertTextFormat, .plain)
}

for col in 10...12 {
let inIdent = try! sk.sendSync(CompletionRequest(
textDocument: TextDocumentIdentifier(url),
position: Position(line: 4, utf16index: col)))
position: Position(line: 5, utf16index: col)))
guard let abc = inIdent.items.first(where: { $0.label == "abc" }) else {
XCTFail("No completion item with label 'abc'")
return
Expand All @@ -130,15 +132,16 @@ final class SwiftCompletionTests: XCTestCase {
// If we switch to server-side filtering this will change.
XCTAssertEqual(abc.kind, .property)
XCTAssertEqual(abc.detail, "Int")
XCTAssertEqual(abc.documentation, .markupContent(MarkupContent(kind: .markdown, value: "Documentation for abc.")))
XCTAssertEqual(abc.filterText, "abc")
XCTAssertEqual(abc.textEdit, TextEdit(range: Position(line: 4, utf16index: 9)..<Position(line: 4, utf16index: col), newText: "abc"))
XCTAssertEqual(abc.textEdit, TextEdit(range: Position(line: 5, utf16index: 9)..<Position(line: 5, utf16index: col), newText: "abc"))
XCTAssertEqual(abc.insertText, "abc")
XCTAssertEqual(abc.insertTextFormat, .plain)
}

let after = try! sk.sendSync(CompletionRequest(
textDocument: TextDocumentIdentifier(url),
position: Position(line: 5, utf16index: 0)))
position: Position(line: 6, utf16index: 0)))
XCTAssertNotEqual(after, selfDot)
}

Expand All @@ -158,11 +161,11 @@ final class SwiftCompletionTests: XCTestCase {
}

func getTestMethodACompletion() -> CompletionItem? {
return getTestMethodCompletion(Position(line: 4, utf16index: 9), label: "test(a: Int)")
return getTestMethodCompletion(Position(line: 5, utf16index: 9), label: "test(a: Int)")
}

func getTestMethodBCompletion() -> CompletionItem? {
return getTestMethodCompletion(Position(line: 8, utf16index: 9), label: "test(b: Int)")
return getTestMethodCompletion(Position(line: 9, utf16index: 9), label: "test(b: Int)")
}

var test = getTestMethodACompletion()
Expand All @@ -171,7 +174,7 @@ final class SwiftCompletionTests: XCTestCase {
XCTAssertEqual(test.kind, .method)
XCTAssertEqual(test.detail, "Void")
XCTAssertEqual(test.filterText, "test(a:)")
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 4, utf16index: 9)..<Position(line: 4, utf16index: 9), newText: "test(a: ${1:Int})"))
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 5, utf16index: 9)..<Position(line: 5, utf16index: 9), newText: "test(a: ${1:Int})"))
XCTAssertEqual(test.insertText, "test(a: ${1:Int})")
XCTAssertEqual(test.insertTextFormat, .snippet)
}
Expand All @@ -182,7 +185,7 @@ final class SwiftCompletionTests: XCTestCase {
XCTAssertEqual(test.kind, .method)
XCTAssertEqual(test.detail, "Void")
XCTAssertEqual(test.filterText, "test(:)")
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 8, utf16index: 9)..<Position(line: 8, utf16index: 9), newText: "test(${1:b: Int})"))
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 9, utf16index: 9)..<Position(line: 9, utf16index: 9), newText: "test(${1:b: Int})"))
XCTAssertEqual(test.insertText, "test(${1:b: Int})")
XCTAssertEqual(test.insertTextFormat, .snippet)
}
Expand All @@ -198,7 +201,7 @@ final class SwiftCompletionTests: XCTestCase {
XCTAssertEqual(test.kind, .method)
XCTAssertEqual(test.detail, "Void")
XCTAssertEqual(test.filterText, "test(a:)")
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 4, utf16index: 9)..<Position(line: 4, utf16index: 9), newText: "test(a: )"))
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 5, utf16index: 9)..<Position(line: 5, utf16index: 9), newText: "test(a: )"))
XCTAssertEqual(test.insertText, "test(a: )")
XCTAssertEqual(test.insertTextFormat, .plain)
}
Expand All @@ -210,7 +213,7 @@ final class SwiftCompletionTests: XCTestCase {
XCTAssertEqual(test.detail, "Void")
XCTAssertEqual(test.filterText, "test(:)")
// FIXME:
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 8, utf16index: 9)..<Position(line: 8, utf16index: 9), newText: "test()"))
XCTAssertEqual(test.textEdit, TextEdit(range: Position(line: 9, utf16index: 9)..<Position(line: 9, utf16index: 9), newText: "test()"))
XCTAssertEqual(test.insertText, "test()")
XCTAssertEqual(test.insertTextFormat, .plain)
}
Expand Down