Skip to content

Commit e9d894c

Browse files
authored
Merge pull request #1092 from ahoppen/ahoppen/diagnose-improvements
Improvements to the diagnose subcommands
2 parents 8371d9d + 31b7fb7 commit e9d894c

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

Sources/Diagnose/RequestInfo.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,16 @@ public struct RequestInfo {
7070
"key.offset: "
7171
Capture(ZeroOrMore(.digit))
7272
}
73-
guard let offsetMatch = requestTemplate.matches(of: offsetRegex).only else {
74-
throw ReductionError("Failed to find key.offset in the request")
73+
if let offsetMatch = requestTemplate.matches(of: offsetRegex).only {
74+
offset = Int(offsetMatch.1)!
75+
requestTemplate.replace(offsetRegex, with: "key.offset: $OFFSET")
76+
} else {
77+
offset = 0
7578
}
76-
offset = Int(offsetMatch.1)!
77-
requestTemplate.replace(offsetRegex, with: "key.offset: $OFFSET")
79+
80+
// If the request contained source text, remove it. We want to pick it up from the file on disk and most (possibly
81+
// all) sourcekitd requests use key.sourcefile if key.sourcetext is missing.
82+
requestTemplate.replace(#/ *key.sourcetext: .*\n/#, with: "")
7883

7984
// Extract source file
8085
let sourceFileRegex = Regex {

Sources/Diagnose/SourcekitdRequestCommand.swift

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import ArgumentParser
1414
import Foundation
15+
import SKSupport
1516
import SourceKitD
1617

1718
import struct TSCBasic.AbsolutePath
@@ -35,15 +36,32 @@ public struct SourceKitdRequestCommand: AsyncParsableCommand {
3536
)
3637
var sourcekitdRequestPath: String
3738

39+
@Option(help: "line:column override for key.offset")
40+
var position: String?
41+
3842
public init() {}
3943

4044
public func run() async throws {
41-
let requestString = try String(contentsOf: URL(fileURLWithPath: sourcekitdRequestPath))
45+
var requestString = try String(contentsOf: URL(fileURLWithPath: sourcekitdRequestPath))
4246

4347
let sourcekitd = try DynamicallyLoadedSourceKitD.getOrCreate(
4448
dylibPath: try! AbsolutePath(validating: sourcekitdPath)
4549
)
4650

51+
if let lineColumn = position?.split(separator: ":", maxSplits: 2).map(Int.init),
52+
lineColumn.count == 2,
53+
let line = lineColumn[0],
54+
let column = lineColumn[1]
55+
{
56+
let requestInfo = try RequestInfo(request: requestString)
57+
58+
let lineTable = LineTable(requestInfo.fileContents)
59+
if let offset = lineTable.utf8OffsetOf(line: line - 1, utf8Column: column - 1) {
60+
print("Adjusting request offset to \(offset)")
61+
requestString.replace(#/key.offset: [0-9]+/#, with: "key.offset: \(offset)")
62+
}
63+
}
64+
4765
let request = try requestString.cString(using: .utf8)!.withUnsafeBufferPointer { buffer in
4866
var error: UnsafeMutablePointer<CChar>?
4967
let req = sourcekitd.api.request_create_from_yaml(buffer.baseAddress!, &error)!
@@ -60,7 +78,17 @@ public struct SourceKitdRequestCommand: AsyncParsableCommand {
6078
}
6179

6280
switch response.error {
63-
case .requestFailed, .requestInvalid, .requestCancelled, .missingRequiredSymbol:
81+
case .requestFailed(let message):
82+
print(message)
83+
throw ExitCode(1)
84+
case .requestInvalid(let message):
85+
print(message)
86+
throw ExitCode(1)
87+
case .requestCancelled:
88+
print("request cancelled")
89+
throw ExitCode(1)
90+
case .missingRequiredSymbol:
91+
print("missing required symbol")
6492
throw ExitCode(1)
6593
case .connectionInterrupted:
6694
throw ExitCode(255)

Sources/SKSupport/LineTable.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,14 @@ extension LineTable {
147147
/// - parameter utf8Column: UTF-8 column offset (zero-based).
148148
@inlinable
149149
public func stringIndexOf(line: Int, utf8Column: Int) -> String.Index? {
150-
guard line < count else {
150+
guard 0 <= line, line < count else {
151151
// Line out of range.
152152
return nil
153153
}
154+
guard 0 <= utf8Column else {
155+
// Column out of range.
156+
return nil
157+
}
154158
let lineSlice = self[line]
155159
return content.utf8.index(lineSlice.startIndex, offsetBy: utf8Column, limitedBy: lineSlice.endIndex)
156160
}

0 commit comments

Comments
 (0)