Skip to content

Commit afd7975

Browse files
committed
WIP
1 parent 9d0a6d5 commit afd7975

File tree

10 files changed

+305
-67
lines changed

10 files changed

+305
-67
lines changed

Copilot for Xcode.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Core/Package.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ let package = Package(
5151
url: "https://github.com/pointfreeco/swift-composable-architecture",
5252
from: "0.55.0"
5353
),
54+
.package(url: "https://github.com/apple/swift-syntax.git", branch: "main"),
5455
].pro,
5556
targets: [
5657
// MARK: - Main
@@ -360,6 +361,7 @@ let package = Package(
360361
.product(name: "OpenAIService", package: "Tool"),
361362
.product(name: "Preferences", package: "Tool"),
362363
.product(name: "ASTParser", package: "Tool"),
364+
.product(name: "SwiftSyntax", package: "swift-syntax"),
363365
],
364366
path: "Sources/ChatContextCollectors/ActiveDocumentChatContextCollector"
365367
),

Core/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/GetCodeFunction.swift

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,22 @@ struct GetCodeFunction: ChatGPTFunction {
1414
}
1515

1616
struct Result: ChatGPTFunctionResult {
17-
struct Context {
18-
var parentName: String
19-
var parentType: String
20-
}
21-
2217
var relativePath: String
2318
var code: String
2419
var range: CursorRange
25-
var context: Context
20+
var context: CodeContext
2621
var type: CodeType
2722
var language: String
2823

2924
var botReadableContent: String {
3025
"""
31-
The \(type.rawValue) code is a part of `\(context.parentType) \(context.parentName)` \
32-
in file \(relativePath).
33-
Range [\(range.start.line), \(range.start.character)] - \
34-
[\(range.end.line), \(range.end.character)]
26+
File: \(relativePath)
27+
Range: \(range)
28+
\(type.rawValue) code
3529
```\(language)
3630
\(code)
3731
```
32+
\(context)
3833
"""
3934
}
4035
}
@@ -74,18 +69,14 @@ struct GetCodeFunction: ChatGPTFunction {
7469
let type = CodeType.selected
7570
let relativePath = content.documentURL.path
7671
.replacingOccurrences(of: content.projectURL.path, with: "")
77-
let context = Result.Context(
78-
parentName: content.documentURL.lastPathComponent,
79-
parentType: "File"
80-
)
8172
let range = selectionRange
8273

8374
await reportProgress("Finish reading code..")
8475
return .init(
8576
relativePath: relativePath,
8677
code: editorContent,
8778
range: range,
88-
context: context,
79+
context: .top,
8980
type: type,
9081
language: language
9182
)
@@ -99,20 +90,34 @@ struct GetCodeResultParser {
9990
let language = editorInformation.language.rawValue
10091
let relativePath = editorInformation.relativePath
10192
let selectionRange = editorInformation.editorContent?.selections.first
93+
let code = {
94+
if editorInformation.selectedContent.isEmpty {
95+
return editorInformation.selectedLines.first ?? ""
96+
}
97+
return editorInformation.selectedContent
98+
}()
10299

103-
if let selectionRange, let node = findSmallestScopeContainingRange(selectionRange) {
104-
let code = {
105-
if editorInformation.selectedContent.isEmpty {
106-
return editorInformation.selectedLines.first ?? ""
107-
}
108-
return editorInformation.selectedContent
109-
}()
100+
guard let astReader = createASTReader() else {
101+
return .init(
102+
relativePath: relativePath,
103+
code: code,
104+
range: selectionRange ?? .zero,
105+
context: .top,
106+
type: .selected,
107+
language: language
108+
)
109+
}
110110

111+
if let selectionRange {
112+
let context = astReader.contextContainingRange(
113+
selectionRange,
114+
in: editorInformation.editorContent?.content ?? ""
115+
)
111116
return .init(
112117
relativePath: relativePath,
113118
code: code,
114119
range: selectionRange,
115-
context: .init(parentName: "", parentType: ""),
120+
context: .top,
116121
type: .selected,
117122
language: language
118123
)
@@ -122,30 +127,20 @@ struct GetCodeResultParser {
122127
relativePath: relativePath,
123128
code: "",
124129
range: selectionRange ?? .zero,
125-
context: .init(parentName: "", parentType: ""),
130+
context: .top,
126131
type: .focused,
127132
language: language
128133
)
129134
}
130135

131-
func findSmallestScopeContainingRange(_ range: CursorRange) -> ASTNode? {
132-
guard let language = {
133-
switch editorInformation.language {
134-
case .builtIn(.swift):
135-
return ParsableLanguage.swift
136-
case .builtIn(.objc), .builtIn(.objcpp):
137-
return ParsableLanguage.objectiveC
138-
default:
139-
return nil
140-
}
141-
}() else { return nil }
142-
143-
let parser = ASTParser(language: language)
144-
guard let tree = parser.parse(editorInformation.editorContent?.content ?? "")
145-
else { return nil }
146-
147-
return tree.smallestNodeContainingRange(range) { node in
148-
ScopeType.allCases.map { $0.rawValue }.contains(node.nodeType)
136+
func createASTReader() -> ASTReader? {
137+
switch editorInformation.language {
138+
case .builtIn(.swift):
139+
return SwiftASTReader()
140+
case .builtIn(.objc), .builtIn(.objcpp):
141+
return SwiftASTReader()
142+
default:
143+
return nil
149144
}
150145
}
151146
}

Core/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/GetEditorInfo.swift

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,31 @@ struct EditorInformation {
1010
let projectURL: URL
1111
let relativePath: String
1212
let language: CodeLanguage
13+
14+
func code(in range: CursorRange) -> String {
15+
return EditorInformation.code(in: selectedLines, inside: range).code
16+
}
17+
18+
static func lines(in code: [String], containing range: CursorRange) -> [String] {
19+
let startIndex = min(max(0, range.start.line), code.endIndex - 1)
20+
let endIndex = min(max(startIndex, range.end.line), code.endIndex - 1)
21+
let selectedLines = code[startIndex...endIndex]
22+
return Array(selectedLines)
23+
}
24+
25+
static func code(in code: [String], inside range: CursorRange) -> (code: String, lines: [String]) {
26+
let rangeLines = lines(in: code, containing: range)
27+
var selectedContent = rangeLines
28+
if !selectedContent.isEmpty {
29+
selectedContent[0] = String(selectedContent[0].dropFirst(range.start.character))
30+
selectedContent[selectedContent.endIndex - 1] = String(
31+
selectedContent[selectedContent.endIndex - 1].dropLast(
32+
selectedContent[selectedContent.endIndex - 1].count - range.end.character
33+
)
34+
)
35+
}
36+
return (selectedContent.joined(), rangeLines)
37+
}
1338
}
1439

1540
func getEditorInformation() -> EditorInformation {
@@ -21,28 +46,14 @@ func getEditorInformation() -> EditorInformation {
2146
.replacingOccurrences(of: projectURL.path, with: "")
2247

2348
if let editorContent, let range = editorContent.selections.first {
24-
let startIndex = min(
25-
max(0, range.start.line),
26-
editorContent.lines.endIndex - 1
27-
)
28-
let endIndex = min(
29-
max(startIndex, range.end.line),
30-
editorContent.lines.endIndex - 1
49+
let (selectedContent, selectedLines) = EditorInformation.code(
50+
in: editorContent.lines,
51+
inside: range
3152
)
32-
let selectedLines = editorContent.lines[startIndex...endIndex]
33-
var selectedContent = selectedLines
34-
if selectedContent.count > 0 {
35-
selectedContent[0] = String(selectedContent[0].dropFirst(range.start.character))
36-
selectedContent[selectedContent.endIndex - 1] = String(
37-
selectedContent[selectedContent.endIndex - 1].dropLast(
38-
selectedContent[selectedContent.endIndex - 1].count - range.end.character
39-
)
40-
)
41-
}
4253
return .init(
4354
editorContent: editorContent,
44-
selectedContent: selectedContent.joined(),
45-
selectedLines: Array(selectedLines),
55+
selectedContent: selectedContent,
56+
selectedLines: selectedLines,
4657
documentURL: documentURL,
4758
projectURL: projectURL,
4859
relativePath: relativePath,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import SuggestionModel
2+
3+
extension CursorPosition: CustomStringConvertible {
4+
var description: String {
5+
"[\(line), \(character)]"
6+
}
7+
}
8+
9+
extension CursorRange: CustomStringConvertible {
10+
var description: String {
11+
"\(start.description) - \(end.description)"
12+
}
13+
}

0 commit comments

Comments
 (0)