-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathRefreshCodeIssuesToolsListRewriter.swift
More file actions
136 lines (129 loc) · 5.65 KB
/
RefreshCodeIssuesToolsListRewriter.swift
File metadata and controls
136 lines (129 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import Foundation
import ProxyCore
package enum RefreshCodeIssuesToolsListRewriter {
package static func rewriteResult(
_ result: JSONValue,
mode: RefreshCodeIssuesMode
) -> JSONValue {
guard case .object(var resultObject) = result,
case .array(let tools) = resultObject["tools"]
else {
return result
}
let rewrittenTools = tools.map { toolValue in
guard case .object(var toolObject) = toolValue,
case .string(let name) = toolObject["name"],
name == RefreshCodeIssuesRequest.toolName
else {
return toolValue
}
toolObject["description"] = .string(description(for: mode))
if mode == .proxy {
toolObject["outputSchema"] = proxyOutputSchema
}
return .object(toolObject)
}
resultObject["tools"] = .array(rewrittenTools)
return .object(resultObject)
}
package static func rewriteResponseDataIfNeeded(
_ responseData: Data,
mode: RefreshCodeIssuesMode
) -> Data {
guard
let object = try? JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any],
let result = object["result"],
let resultValue = JSONValue(any: result)
else {
return responseData
}
let rewrittenResult = rewriteResult(resultValue, mode: mode)
guard rewrittenResult.foundationObject as? [String: Any] != nil else {
return responseData
}
var rewrittenObject = object
rewrittenObject["result"] = rewrittenResult.foundationObject
guard JSONSerialization.isValidJSONObject(rewrittenObject),
let rewrittenData = try? JSONSerialization.data(withJSONObject: rewrittenObject, options: [])
else {
return responseData
}
return rewrittenData
}
private static func description(for mode: RefreshCodeIssuesMode) -> String {
switch mode {
case .proxy:
return """
Returns file-scoped diagnostics for a source file. By default, the proxy serves this via Xcode navigator issues to avoid switching Spaces. Use --refresh-code-issues-mode upstream to use Xcode's native live diagnostics path instead.
"""
case .upstream:
return """
Returns file-scoped diagnostics for a source file. This proxy is configured to pass through to Xcode's native live diagnostics path.
"""
}
}
private static let proxyOutputSchema: JSONValue = .object([
"type": .string("object"),
"required": .array([
.string("issues"),
.string("truncated"),
.string("totalFound"),
]),
"properties": .object([
"message": .object([
"type": .string("string"),
"description": .string("Optional message with additional information about the search results"),
]),
"truncated": .object([
"type": .string("boolean"),
"description": .string("Whether results were truncated due to exceeding 100 issues"),
]),
"totalFound": .object([
"type": .string("integer"),
"description": .string("Total number of issues before truncation"),
]),
"issues": .object([
"type": .string("array"),
"description": .string("The list of current issues matching the input filters"),
"items": .object([
"type": .string("object"),
"required": .array([
.string("message"),
.string("severity"),
]),
"properties": .object([
"severity": .object([
"type": .string("string"),
"description": .string("The severity of issue (error, warning, remark)"),
]),
"line": .object([
"type": .string("integer"),
"description": .string("The line number where the issue was detected, if known"),
]),
"vitality": .object([
"type": .string("string"),
"enum": .array([
.string("fresh"),
.string("stale"),
]),
"description": .string("Whether an issue from a previous build is known to still be relevant or whether something might have changed since it was emitted (for example if the source file has been edited and it isn't yet known whether that edit fixes the issue). Possible values: (fresh, stale)"),
]),
"path": .object([
"type": .string("string"),
"description": .string("The file path where the issue was detected, if any"),
]),
"message": .object([
"type": .string("string"),
"description": .string("The message describing the issue"),
]),
"category": .object([
"type": .string("string"),
"description": .string("The category of the issue, if known"),
]),
]),
]),
]),
]),
])
}