Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #49 from benlangmuir/fold-url
[swift] Fix folding range for comment.url, comment.mark types
  • Loading branch information
benlangmuir committed Dec 14, 2018
2 parents 31a4e91 + cf18088 commit d7b0b62
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 236 deletions.
23 changes: 22 additions & 1 deletion Sources/LanguageServerProtocol/FoldingRange.swift
Expand Up @@ -52,7 +52,13 @@ public struct FoldingRange: ResponseType, Hashable {
/// is used to categorize folding ranges and used by commands like 'Fold all comments'.
public var kind: FoldingRangeKind?

public init(startLine: Int, startUTF16Index: Int? = nil, endLine: Int, endUTF16Index: Int? = nil, kind: FoldingRangeKind? = nil) {
public init(
startLine: Int,
startUTF16Index: Int? = nil,
endLine: Int,
endUTF16Index: Int? = nil,
kind: FoldingRangeKind? = nil)
{
self.startLine = startLine
self.startUTF16Index = startUTF16Index
self.endLine = endLine
Expand All @@ -70,3 +76,18 @@ extension FoldingRange: Codable {
case kind
}
}

extension FoldingRange: Comparable {

public static func <(lhs: FoldingRange, rhs: FoldingRange) -> Bool {
return lhs.comparableKey < rhs.comparableKey
}

private var comparableKey: (Int, Int, Int, Int, String) {
return (
startLine,
startUTF16Index ?? Int.max,
endLine, endUTF16Index ?? Int.max,
kind?.rawValue ?? "")
}
}
15 changes: 8 additions & 7 deletions Sources/SourceKit/sourcekitd/SwiftLanguageServer.swift
Expand Up @@ -587,13 +587,8 @@ extension SwiftLanguageServer {
currentComment = nil
}

guard hasReachedLimit == false else {
req.reply(ranges)
return
}

var structureStack: [SKResponseArray] = [substructure]
while let substructure = structureStack.popLast() {
while let substructure = structureStack.popLast(), !hasReachedLimit {
substructure.forEach { _, value in
if let offset: Int = value[self.keys.bodyoffset],
let length: Int = value[self.keys.bodylength],
Expand All @@ -612,6 +607,7 @@ extension SwiftLanguageServer {
}
}

ranges.sort()
req.reply(ranges)
}

Expand Down Expand Up @@ -689,7 +685,12 @@ func makeLocalSwiftServer(client: MessageHandler, sourcekitd: AbsolutePath, buil

extension sourcekitd_uid_t {
func isCommentKind(_ vals: sourcekitd_values) -> Bool {
return self == vals.syntaxtype_comment || isDocCommentKind(vals)
switch self {
case vals.syntaxtype_comment, vals.syntaxtype_comment_marker, vals.syntaxtype_comment_url:
return true
default:
return isDocCommentKind(vals)
}
}

func isDocCommentKind(_ vals: sourcekitd_values) -> Bool {
Expand Down
4 changes: 4 additions & 0 deletions Sources/SourceKit/sourcekitd/SwiftSourceKitFramework.swift
Expand Up @@ -345,6 +345,8 @@ struct sourcekitd_values {
let ref_generic_type_param: sourcekitd_uid_t
let ref_module: sourcekitd_uid_t
let syntaxtype_comment: sourcekitd_uid_t
let syntaxtype_comment_marker: sourcekitd_uid_t
let syntaxtype_comment_url: sourcekitd_uid_t
let syntaxtype_doccomment: sourcekitd_uid_t
let syntaxtype_doccomment_field: sourcekitd_uid_t

Expand Down Expand Up @@ -432,6 +434,8 @@ struct sourcekitd_values {
ref_generic_type_param = api.uid_get_from_cstr("source.lang.swift.ref.generic_type_param")!
ref_module = api.uid_get_from_cstr("source.lang.swift.ref.module")!
syntaxtype_comment = api.uid_get_from_cstr("source.lang.swift.syntaxtype.comment")!
syntaxtype_comment_marker = api.uid_get_from_cstr("source.lang.swift.syntaxtype.comment.mark")!
syntaxtype_comment_url = api.uid_get_from_cstr("source.lang.swift.syntaxtype.comment.url")!
syntaxtype_doccomment = api.uid_get_from_cstr("source.lang.swift.syntaxtype.doccomment")!
syntaxtype_doccomment_field = api.uid_get_from_cstr("source.lang.swift.syntaxtype.doccomment.field")!

Expand Down
190 changes: 190 additions & 0 deletions Tests/SourceKitTests/FoldingRangeTests.swift
@@ -0,0 +1,190 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import LanguageServerProtocol
import SKSupport
import SKTestSupport
import XCTest

@testable import SourceKit

final class FoldingRangeTests: XCTestCase {

typealias FoldingRangeCapabilities = TextDocumentClientCapabilities.FoldingRange

/// Base document text to use for folding range tests.
let text: String = """
/// DC1
/// - Returns: DC1
/**
DC2
- Parameter param: DC2
- Throws: DC2
DC2
DC2
- Returns: DC2
*/
struct S {
//c1
//c2
/*
c3
*/
var abc: Int
func test(a: Int) {
guard a > 0 else { return }
self.abc = a
}
/* c4 */
}
//
// MARK: - A mark! -
//
//
// FIXME: a fixme
//
// a https://www.example.com URL
"""

/// Connection and lifetime management for the service.
var connection: TestSourceKitServer! = nil

/// The primary interface to make requests to the SourceKitServer.
var sk: TestClient! = nil

/// The server's workspace data. Accessing this is unsafe if the server does so concurrently.
var workspace: Workspace! = nil

override func tearDown() {
workspace = nil
sk = nil
connection = nil
}

func initialize(capabilities: FoldingRangeCapabilities) {
connection = TestSourceKitServer()
sk = connection.client
var documentCapabilities = TextDocumentClientCapabilities()
documentCapabilities.foldingRange = capabilities
_ = try! sk.sendSync(InitializeRequest(
processId: nil,
rootPath: nil,
rootURL: nil,
initializationOptions: nil,
capabilities: ClientCapabilities(workspace: nil, textDocument: documentCapabilities),
trace: .off,
workspaceFolders: nil))

workspace = connection.server!.workspace!
}

func getFoldingRangeRequest(text: String? = nil) -> FoldingRangeRequest {
let url = URL(fileURLWithPath: "/a.swift")
sk.allowUnexpectedNotification = true

sk.send(DidOpenTextDocument(textDocument: TextDocumentItem(
url: url,
language: .swift,
version: 12,
text:
text ?? self.text)))

return FoldingRangeRequest(textDocument: TextDocumentIdentifier(url))
}

func testPartialLineFolding() {
var capabilities = FoldingRangeCapabilities()
capabilities.lineFoldingOnly = false
initialize(capabilities: capabilities)

let request = getFoldingRangeRequest()
let ranges = try! sk.sendSync(request)!

XCTAssertEqual(ranges, [
FoldingRange(startLine: 0, startUTF16Index: 0, endLine: 2, endUTF16Index: 0, kind: .comment),
FoldingRange(startLine: 3, startUTF16Index: 0, endLine: 13, endUTF16Index: 2, kind: .comment),
FoldingRange(startLine: 14, startUTF16Index: 10, endLine: 27, endUTF16Index: 0, kind: nil),
FoldingRange(startLine: 15, startUTF16Index: 2, endLine: 16, endUTF16Index: 0, kind: .comment),
FoldingRange(startLine: 16, startUTF16Index: 2, endLine: 17, endUTF16Index: 0, kind: .comment),
FoldingRange(startLine: 17, startUTF16Index: 2, endLine: 19, endUTF16Index: 4, kind: .comment),
FoldingRange(startLine: 22, startUTF16Index: 21, endLine: 25, endUTF16Index: 2, kind: nil),
FoldingRange(startLine: 23, startUTF16Index: 22, endLine: 23, endUTF16Index: 30, kind: nil),
FoldingRange(startLine: 26, startUTF16Index: 2, endLine: 26, endUTF16Index: 10, kind: .comment),
FoldingRange(startLine: 29, startUTF16Index: 0, endLine: 32, endUTF16Index: 0, kind: .comment),
FoldingRange(startLine: 33, startUTF16Index: 0, endLine: 36, endUTF16Index: 0, kind: .comment),
FoldingRange(startLine: 37, startUTF16Index: 0, endLine: 38, endUTF16Index: 0, kind: .comment),
])
}

func testLineFoldingOnly() {
var capabilities = FoldingRangeCapabilities()
capabilities.lineFoldingOnly = true
initialize(capabilities: capabilities)

let request = getFoldingRangeRequest()
let ranges = try! sk.sendSync(request)!

XCTAssertEqual(ranges, [
FoldingRange(startLine: 0, endLine: 1, kind: .comment),
FoldingRange(startLine: 3, endLine: 12, kind: .comment),
FoldingRange(startLine: 14, endLine: 26, kind: nil),
FoldingRange(startLine: 17, endLine: 18, kind: .comment),
FoldingRange(startLine: 22, endLine: 24, kind: nil),
FoldingRange(startLine: 29, endLine: 31, kind: .comment),
FoldingRange(startLine: 33, endLine: 35, kind: .comment),
])
}

func testRangeLimit() {
var capabilities = FoldingRangeCapabilities()
capabilities.lineFoldingOnly = false

capabilities.rangeLimit = -100
initialize(capabilities: capabilities)
XCTAssertEqual(try! sk.sendSync(getFoldingRangeRequest())!.count, 0)

capabilities.rangeLimit = 0
initialize(capabilities: capabilities)
XCTAssertEqual(try! sk.sendSync(getFoldingRangeRequest())!.count, 0)

capabilities.rangeLimit = 4
initialize(capabilities: capabilities)
XCTAssertEqual(try! sk.sendSync(getFoldingRangeRequest())!.count, 4)

capabilities.rangeLimit = 5000
initialize(capabilities: capabilities)
XCTAssertEqual(try! sk.sendSync(getFoldingRangeRequest())!.count, 12)

capabilities.rangeLimit = nil
initialize(capabilities: capabilities)
XCTAssertEqual(try! sk.sendSync(getFoldingRangeRequest())!.count, 12)
}

func testEmptyText() {
let capabilities = FoldingRangeCapabilities()
initialize(capabilities: capabilities)

let request = getFoldingRangeRequest(text: "")
let ranges = try! sk.sendSync(request)!

XCTAssertEqual(ranges.count, 0)
}
}

0 comments on commit d7b0b62

Please sign in to comment.