//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2021 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 SourceKitD import LanguageServerProtocol import LSPLogging /// A ranged token in the document used for syntax highlighting. public struct SyntaxHighlightingToken: Hashable { /// The range of the token in the document. Must be on a single line. public var range: Range { didSet { assert(range.lowerBound.line == range.upperBound.line) } } /// The token type. public var kind: Kind /// Additional metadata about the token. public var modifiers: Modifiers /// The (inclusive) start position of the token. public var start: Position { range.lowerBound } /// The (exclusive) end position of the token. public var end: Position { range.upperBound } /// The length of the token in UTF-16 code units. public var utf16length: Int { end.utf16index - start.utf16index } public init(range: Range, kind: Kind, modifiers: Modifiers = []) { assert(range.lowerBound.line == range.upperBound.line) self.range = range self.kind = kind self.modifiers = modifiers } public init(start: Position, utf16length: Int, kind: Kind, modifiers: Modifiers = []) { let range = start..= 0) assert(charDelta >= 0) previous = token.start rawTokens += [ UInt32(lineDelta), UInt32(charDelta), UInt32(token.utf16length), token.kind.rawValue, token.modifiers.rawValue ] } return rawTokens } /// Merges the tokens in this array into a new token array, /// preferring the given array's tokens if duplicate ranges are /// found. public func mergingTokens(with other: [SyntaxHighlightingToken]) -> [SyntaxHighlightingToken] { let otherRanges = Set(other.map(\.range)) return filter { !otherRanges.contains($0.range) } + other } }