mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
Add `.swift-format` to the repo and format the repo with `swift-format`. This commit does not add any automation to enforce formatting of sourcekit-lsp in CI. The goal of this commit is to get the majority of source changes out of the way so that the diff of actually enforcing formatting will have fewer changes or conflicts.
119 lines
4.1 KiB
Swift
119 lines
4.1 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2022 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 Foundation
|
|
import LSPLogging
|
|
import LanguageServerProtocol
|
|
import SKSupport
|
|
import SourceKitD
|
|
|
|
struct InterfaceInfo {
|
|
var contents: String
|
|
}
|
|
|
|
extension SwiftLanguageServer {
|
|
public func openInterface(_ request: OpenInterfaceRequest) async throws -> InterfaceDetails? {
|
|
let uri = request.textDocument.uri
|
|
let moduleName = request.moduleName
|
|
let name = request.name
|
|
let symbol = request.symbolUSR
|
|
let interfaceFilePath = self.generatedInterfacesPath.appendingPathComponent("\(name).swiftinterface")
|
|
let interfaceDocURI = DocumentURI(interfaceFilePath)
|
|
// has interface already been generated
|
|
if let snapshot = self.documentManager.latestSnapshot(interfaceDocURI) {
|
|
return await self.interfaceDetails(request: request, uri: interfaceDocURI, snapshot: snapshot, symbol: symbol)
|
|
} else {
|
|
// generate interface
|
|
let interfaceInfo = try await self.openInterface(
|
|
request: request,
|
|
uri: uri,
|
|
name: moduleName,
|
|
interfaceURI: interfaceDocURI
|
|
)
|
|
do {
|
|
// write to file
|
|
try interfaceInfo.contents.write(to: interfaceFilePath, atomically: true, encoding: String.Encoding.utf8)
|
|
// store snapshot
|
|
let snapshot = try self.documentManager.open(
|
|
interfaceDocURI,
|
|
language: .swift,
|
|
version: 0,
|
|
text: interfaceInfo.contents
|
|
)
|
|
return await self.interfaceDetails(request: request, uri: interfaceDocURI, snapshot: snapshot, symbol: symbol)
|
|
} catch {
|
|
throw ResponseError.unknown(error.localizedDescription)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Open the Swift interface for a module.
|
|
///
|
|
/// - Parameters:
|
|
/// - request: The OpenInterfaceRequest.
|
|
/// - uri: The document whose compiler arguments should be used to generate the interface.
|
|
/// - name: The name of the module whose interface should be generated.
|
|
/// - interfaceURI: The file where the generated interface should be written.
|
|
private func openInterface(
|
|
request: OpenInterfaceRequest,
|
|
uri: DocumentURI,
|
|
name: String,
|
|
interfaceURI: DocumentURI
|
|
) async throws -> InterfaceInfo {
|
|
let keys = self.keys
|
|
let skreq = SKDRequestDictionary(sourcekitd: sourcekitd)
|
|
skreq[keys.request] = requests.editor_open_interface
|
|
skreq[keys.modulename] = name
|
|
if request.groupNames.count > 0 {
|
|
skreq[keys.groupname] = request.groupNames
|
|
}
|
|
skreq[keys.name] = interfaceURI.pseudoPath
|
|
skreq[keys.synthesizedextensions] = 1
|
|
if let compileCommand = await self.buildSettings(for: uri) {
|
|
skreq[keys.compilerargs] = compileCommand.compilerArgs
|
|
}
|
|
|
|
let dict = try await self.sourcekitd.send(skreq)
|
|
return InterfaceInfo(contents: dict[keys.sourcetext] ?? "")
|
|
}
|
|
|
|
private func interfaceDetails(
|
|
request: OpenInterfaceRequest,
|
|
uri: DocumentURI,
|
|
snapshot: DocumentSnapshot,
|
|
symbol: String?
|
|
) async -> InterfaceDetails {
|
|
do {
|
|
guard let symbol = symbol else {
|
|
return InterfaceDetails(uri: uri, position: nil)
|
|
}
|
|
let keys = self.keys
|
|
let skreq = SKDRequestDictionary(sourcekitd: sourcekitd)
|
|
|
|
skreq[keys.request] = requests.find_usr
|
|
skreq[keys.sourcefile] = uri.pseudoPath
|
|
skreq[keys.usr] = symbol
|
|
|
|
let dict = try await self.sourcekitd.send(skreq)
|
|
if let offset: Int = dict[keys.offset],
|
|
let position = snapshot.positionOf(utf8Offset: offset)
|
|
{
|
|
return InterfaceDetails(uri: uri, position: position)
|
|
} else {
|
|
return InterfaceDetails(uri: uri, position: nil)
|
|
}
|
|
} catch {
|
|
return InterfaceDetails(uri: uri, position: nil)
|
|
}
|
|
}
|
|
}
|