Skip to content

Commit 06df823

Browse files
authored
Merge pull request #414 from fwcd/semantic-tokens
2 parents 9f7bfc0 + f83f7f2 commit 06df823

17 files changed

+1645
-36
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ SourceKit-LSP is still in early development, so you may run into rough edges wit
4848
| Local Refactoring || |
4949
| Formatting || |
5050
| Folding || |
51-
| Syntax Highlighting | | Not currently part of LSP. |
51+
| Syntax Highlighting | | Both syntactic and semantic tokens |
5252
| Document Symbols || |
5353

5454

Sources/LSPLogging/Logging.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ public func orLog<R>(
6262
}
6363
}
6464

65+
/// Logs the time that the given block takes to execute in milliseconds.
66+
public func logExecutionTime<R>(
67+
_ prefix: String = #function,
68+
level: LogLevel = .default,
69+
logger: Logger = Logger.shared,
70+
_ block: () throws -> R
71+
) rethrows -> R {
72+
let start = Date()
73+
let result = try block()
74+
let deltaMs = -start.timeIntervalSinceNow * 1000
75+
logger.log(
76+
"\(prefix)\(prefix.isEmpty ? "" : " ")took \(String(format: "%.2f", deltaMs)) ms to execute",
77+
level: level
78+
)
79+
return result
80+
}
81+
6582
public protocol LogHandler: AnyObject {
6683
func handle(_ message: String, level: LogLevel)
6784
}

Sources/LanguageServerProtocol/Requests/DocumentSymbolRequest.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public struct DocumentSymbol: Hashable, Codable {
9191
public var selectionRange: Range<Position>
9292

9393
/// Children of this symbol, e.g. properties of a class.
94-
public var children: [DocumentSymbol]?
94+
public var children: [DocumentSymbol]
9595

9696
public init(
9797
name: String,
@@ -100,7 +100,7 @@ public struct DocumentSymbol: Hashable, Codable {
100100
deprecated: Bool? = nil,
101101
range: Range<Position>,
102102
selectionRange: Range<Position>,
103-
children: [DocumentSymbol]? = nil)
103+
children: [DocumentSymbol] = [])
104104
{
105105
self.name = name
106106
self.detail = detail

Sources/LanguageServerProtocol/Requests/WorkspaceSemanticTokensRefreshRequest.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@
1616
public struct WorkspaceSemanticTokensRefreshRequest: RequestType, Hashable {
1717
public static let method: String = "workspace/semanticTokens/refresh"
1818
public typealias Response = VoidResponse
19+
20+
public init() {}
1921
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SourceKitLSP
14+
import LanguageServerProtocol
15+
16+
extension Array where Element == SyntaxHighlightingToken {
17+
/// Decodes the LSP representation of syntax highlighting tokens
18+
public init(lspEncodedTokens rawTokens: [UInt32]) {
19+
self.init()
20+
assert(rawTokens.count.isMultiple(of: 5))
21+
reserveCapacity(rawTokens.count / 5)
22+
23+
var current = Position(line: 0, utf16index: 0)
24+
25+
for i in stride(from: 0, to: rawTokens.count, by: 5) {
26+
let lineDelta = Int(rawTokens[i])
27+
let charDelta = Int(rawTokens[i + 1])
28+
let length = Int(rawTokens[i + 2])
29+
let rawKind = rawTokens[i + 3]
30+
let rawModifiers = rawTokens[i + 4]
31+
32+
current.line += lineDelta
33+
34+
if lineDelta == 0 {
35+
current.utf16index += charDelta
36+
} else {
37+
current.utf16index = charDelta
38+
}
39+
40+
guard let kind = SyntaxHighlightingToken.Kind(rawValue: rawKind) else { continue }
41+
let modifiers = SyntaxHighlightingToken.Modifiers(rawValue: rawModifiers)
42+
43+
append(SyntaxHighlightingToken(
44+
start: current,
45+
utf16length: length,
46+
kind: kind,
47+
modifiers: modifiers
48+
))
49+
}
50+
}
51+
}

Sources/SourceKitD/SKDResponseDictionary.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,31 @@ public final class SKDResponseDictionary {
3030
return sourcekitd.api.variant_dictionary_get_string(dict, key).map(String.init(cString:))
3131
}
3232
public subscript(key: sourcekitd_uid_t?) -> Int? {
33-
return Int(sourcekitd.api.variant_dictionary_get_int64(dict, key))
33+
let value = sourcekitd.api.variant_dictionary_get_value(dict, key)
34+
if sourcekitd.api.variant_get_type(value) == SOURCEKITD_VARIANT_TYPE_INT64 {
35+
return Int(sourcekitd.api.variant_int64_get_value(value))
36+
} else {
37+
return nil
38+
}
3439
}
3540
public subscript(key: sourcekitd_uid_t?) -> Bool? {
36-
return sourcekitd.api.variant_dictionary_get_bool(dict, key)
41+
let value = sourcekitd.api.variant_dictionary_get_value(dict, key)
42+
if sourcekitd.api.variant_get_type(value) == SOURCEKITD_VARIANT_TYPE_BOOL {
43+
return sourcekitd.api.variant_bool_get_value(value)
44+
} else {
45+
return nil
46+
}
3747
}
3848
public subscript(key: sourcekitd_uid_t?) -> sourcekitd_uid_t? {
3949
return sourcekitd.api.variant_dictionary_get_uid(dict, key)
4050
}
4151
public subscript(key: sourcekitd_uid_t?) -> SKDResponseArray? {
42-
return SKDResponseArray(sourcekitd.api.variant_dictionary_get_value(dict, key), response: resp)
52+
let value = sourcekitd.api.variant_dictionary_get_value(dict, key)
53+
if sourcekitd.api.variant_get_type(value) == SOURCEKITD_VARIANT_TYPE_ARRAY {
54+
return SKDResponseArray(value, response: resp)
55+
} else {
56+
return nil
57+
}
4358
}
4459
}
4560

Sources/SourceKitD/sourcekitd_uids.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public struct sourcekitd_keys {
1616
public let actionname: sourcekitd_uid_t
1717
public let actionuid: sourcekitd_uid_t
1818
public let annotated_decl: sourcekitd_uid_t
19+
public let annotations: sourcekitd_uid_t
1920
public let associated_usrs: sourcekitd_uid_t
2021
public let bodylength: sourcekitd_uid_t
2122
public let bodyoffset: sourcekitd_uid_t
@@ -40,6 +41,7 @@ public struct sourcekitd_keys {
4041
public let filepath: sourcekitd_uid_t
4142
public let fixits: sourcekitd_uid_t
4243
public let id: sourcekitd_uid_t
44+
public let is_system: sourcekitd_uid_t
4345
public let kind: sourcekitd_uid_t
4446
public let length: sourcekitd_uid_t
4547
public let line: sourcekitd_uid_t
@@ -61,6 +63,7 @@ public struct sourcekitd_keys {
6163
public let substructure: sourcekitd_uid_t
6264
public let syntactic_only: sourcekitd_uid_t
6365
public let syntaxmap: sourcekitd_uid_t
66+
public let enablesyntaxmap: sourcekitd_uid_t
6467
public let text: sourcekitd_uid_t
6568
public let typename: sourcekitd_uid_t
6669
public let usr: sourcekitd_uid_t
@@ -86,6 +89,7 @@ public struct sourcekitd_keys {
8689
actionname = api.uid_get_from_cstr("key.actionname")!
8790
actionuid = api.uid_get_from_cstr("key.actionuid")!
8891
annotated_decl = api.uid_get_from_cstr("key.annotated_decl")!
92+
annotations = api.uid_get_from_cstr("key.annotations")!
8993
associated_usrs = api.uid_get_from_cstr("key.associated_usrs")!
9094
bodylength = api.uid_get_from_cstr("key.bodylength")!
9195
bodyoffset = api.uid_get_from_cstr("key.bodyoffset")!
@@ -110,6 +114,7 @@ public struct sourcekitd_keys {
110114
filepath = api.uid_get_from_cstr("key.filepath")!
111115
fixits = api.uid_get_from_cstr("key.fixits")!
112116
id = api.uid_get_from_cstr("key.id")!
117+
is_system = api.uid_get_from_cstr("key.is_system")!
113118
kind = api.uid_get_from_cstr("key.kind")!
114119
length = api.uid_get_from_cstr("key.length")!
115120
line = api.uid_get_from_cstr("key.line")!
@@ -131,6 +136,7 @@ public struct sourcekitd_keys {
131136
substructure = api.uid_get_from_cstr("key.substructure")!
132137
syntactic_only = api.uid_get_from_cstr("key.syntactic_only")!
133138
syntaxmap = api.uid_get_from_cstr("key.syntaxmap")!
139+
enablesyntaxmap = api.uid_get_from_cstr("key.enablesyntaxmap")!
134140
text = api.uid_get_from_cstr("key.text")!
135141
typename = api.uid_get_from_cstr("key.typename")!
136142
usr = api.uid_get_from_cstr("key.usr")!
@@ -272,12 +278,20 @@ public struct sourcekitd_values {
272278
public let decl_generic_type_param: sourcekitd_uid_t
273279
public let ref_generic_type_param: sourcekitd_uid_t
274280
public let ref_module: sourcekitd_uid_t
281+
public let syntaxtype_attribute_builtin: sourcekitd_uid_t
275282
public let syntaxtype_comment: sourcekitd_uid_t
276283
public let syntaxtype_comment_marker: sourcekitd_uid_t
277284
public let syntaxtype_comment_url: sourcekitd_uid_t
278285
public let syntaxtype_doccomment: sourcekitd_uid_t
279286
public let syntaxtype_doccomment_field: sourcekitd_uid_t
287+
public let syntaxtype_keyword: sourcekitd_uid_t
288+
public let syntaxtype_number: sourcekitd_uid_t
289+
public let syntaxtype_string: sourcekitd_uid_t
290+
public let syntaxtype_string_interpolation_anchor: sourcekitd_uid_t
291+
public let syntaxtype_type_identifier: sourcekitd_uid_t
292+
public let syntaxtype_identifier: sourcekitd_uid_t
280293
public let expr_object_literal: sourcekitd_uid_t
294+
public let expr_call: sourcekitd_uid_t
281295

282296
public let kind_keyword: sourcekitd_uid_t
283297

@@ -367,12 +381,20 @@ public struct sourcekitd_values {
367381
decl_generic_type_param = api.uid_get_from_cstr("source.lang.swift.decl.generic_type_param")!
368382
ref_generic_type_param = api.uid_get_from_cstr("source.lang.swift.ref.generic_type_param")!
369383
ref_module = api.uid_get_from_cstr("source.lang.swift.ref.module")!
384+
syntaxtype_attribute_builtin = api.uid_get_from_cstr("source.lang.swift.syntaxtype.attribute.builtin")!
370385
syntaxtype_comment = api.uid_get_from_cstr("source.lang.swift.syntaxtype.comment")!
371386
syntaxtype_comment_marker = api.uid_get_from_cstr("source.lang.swift.syntaxtype.comment.mark")!
372387
syntaxtype_comment_url = api.uid_get_from_cstr("source.lang.swift.syntaxtype.comment.url")!
373388
syntaxtype_doccomment = api.uid_get_from_cstr("source.lang.swift.syntaxtype.doccomment")!
374389
syntaxtype_doccomment_field = api.uid_get_from_cstr("source.lang.swift.syntaxtype.doccomment.field")!
390+
syntaxtype_keyword = api.uid_get_from_cstr("source.lang.swift.syntaxtype.keyword")!
391+
syntaxtype_number = api.uid_get_from_cstr("source.lang.swift.syntaxtype.number")!
392+
syntaxtype_string = api.uid_get_from_cstr("source.lang.swift.syntaxtype.string")!
393+
syntaxtype_string_interpolation_anchor = api.uid_get_from_cstr("source.lang.swift.syntaxtype.string_interpolation_anchor")!
394+
syntaxtype_type_identifier = api.uid_get_from_cstr("source.lang.swift.syntaxtype.typeidentifier")!
395+
syntaxtype_identifier = api.uid_get_from_cstr("source.lang.swift.syntaxtype.identifier")!
375396
expr_object_literal = api.uid_get_from_cstr("source.lang.swift.expr.object_literal")!
397+
expr_call = api.uid_get_from_cstr("source.lang.swift.expr.call")!
376398

377399
kind_keyword = api.uid_get_from_cstr("source.lang.swift.keyword")!
378400
}

Sources/SourceKitLSP/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ endif()
88
add_library(SourceKitLSP
99
CapabilityRegistry.swift
1010
DocumentManager.swift
11+
DocumentTokens.swift
1112
IndexStoreDB+MainFilesProvider.swift
1213
SourceKitIndexDelegate.swift
1314
SourceKitLSPCommandMetadata.swift
@@ -30,6 +31,8 @@ target_sources(SourceKitLSP PRIVATE
3031
Swift/SourceKitD+ResponseError.swift
3132
Swift/SwiftCommand.swift
3233
Swift/SwiftLanguageServer.swift
34+
Swift/SyntaxHighlightingToken.swift
35+
Swift/SyntaxHighlightingTokenParser.swift
3336
Swift/VariableTypeInfo.swift)
3437
set_target_properties(SourceKitLSP PROPERTIES
3538
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})

0 commit comments

Comments
 (0)