Skip to content

Commit fd79c3d

Browse files
committed
Revert "Merge pull request #1831 from woolsweater/the-trail-is-closed"
This reverts commit 21dfaf0, reversing changes made to f900b4e.
1 parent c3f97b9 commit fd79c3d

File tree

7 files changed

+80
-459
lines changed

7 files changed

+80
-459
lines changed

Sources/SourceKitLSP/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ target_sources(SourceKitLSP PRIVATE
2626
)
2727
target_sources(SourceKitLSP PRIVATE
2828
Swift/AdjustPositionToStartOfIdentifier.swift
29-
Swift/ClosureCompletionFormat.swift
3029
Swift/CodeActions/AddDocumentation.swift
3130
Swift/CodeActions/ConvertIntegerLiteral.swift
3231
Swift/CodeActions/ConvertJSONToCodableStruct.swift

Sources/SourceKitLSP/Swift/ClosureCompletionFormat.swift

Lines changed: 0 additions & 73 deletions
This file was deleted.

Sources/SourceKitLSP/Swift/CodeCompletionSession.swift

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,9 @@ class CodeCompletionSession {
323323
var parser = Parser(exprToExpand)
324324
let expr = ExprSyntax.parse(from: &parser)
325325
guard let call = OutermostFunctionCallFinder.findOutermostFunctionCall(in: expr),
326-
let expandedCall = ExpandEditorPlaceholdersToLiteralClosures.refactor(
326+
let expandedCall = ExpandEditorPlaceholdersToTrailingClosures.refactor(
327327
syntax: call,
328-
in: ExpandEditorPlaceholdersToLiteralClosures.Context(
329-
format: .custom(
330-
ClosureCompletionFormat(indentationWidth: indentationWidth),
331-
allowNestedPlaceholders: true
332-
)
333-
)
328+
in: ExpandEditorPlaceholdersToTrailingClosures.Context(indentationWidth: indentationWidth)
334329
)
335330
else {
336331
return nil
@@ -339,7 +334,7 @@ class CodeCompletionSession {
339334
let bytesToExpand = Array(exprToExpand.utf8)
340335

341336
var expandedBytes: [UInt8] = []
342-
// Add the prefix that we stripped off to allow expression parsing
337+
// Add the prefix that we stripped of to allow expression parsing
343338
expandedBytes += strippedPrefix.utf8
344339
// Add any part of the expression that didn't end up being part of the function call
345340
expandedBytes += bytesToExpand[0..<call.position.utf8Offset]

Sources/SourceKitLSP/Swift/RewriteSourceKitPlaceholders.swift

Lines changed: 19 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -14,166 +14,34 @@ import Foundation
1414
import SKLogging
1515
@_spi(RawSyntax) import SwiftSyntax
1616

17-
/// Translate SourceKit placeholder syntax — `<#foo#>` — in `input` to LSP
18-
/// placeholder syntax: `${n:foo}`.
19-
///
20-
/// If `clientSupportsSnippets` is `false`, the placeholder is rendered as an
21-
/// empty string, to prevent the client from inserting special placeholder
22-
/// characters as if they were literal text.
23-
@_spi(Testing)
24-
public func rewriteSourceKitPlaceholders(in input: String, clientSupportsSnippets: Bool) -> String {
25-
var result = ""
26-
var nextPlaceholderNumber = 1
27-
// Current stack of nested placeholders, most nested last. Each element needs
28-
// to be rendered inside the element before it.
29-
var placeholders: [(number: Int, contents: String)] = []
30-
let tokens = tokenize(input)
31-
for token in tokens {
32-
switch token {
33-
case let .text(text):
34-
if placeholders.isEmpty {
35-
result += text
36-
} else {
37-
placeholders.latest.contents += text
38-
}
39-
40-
case let .curlyBrace(brace):
41-
if placeholders.isEmpty {
42-
result.append(brace)
43-
} else {
44-
// Braces are only escaped _inside_ a placeholder; otherwise the client
45-
// would include the backslashes literally.
46-
placeholders.latest.contents.append(contentsOf: ["\\", brace])
47-
}
48-
49-
case .placeholderOpen:
50-
placeholders.append((number: nextPlaceholderNumber, contents: ""))
51-
nextPlaceholderNumber += 1
52-
53-
case .placeholderClose:
54-
guard let (number, placeholderBody) = placeholders.popLast() else {
55-
logger.fault("Invalid placeholder in \(input)")
56-
return input
57-
}
58-
guard let displayName = nameForSnippet(placeholderBody) else {
59-
logger.fault("Failed to decode placeholder \(placeholderBody) in \(input)")
60-
return input
61-
}
62-
let placeholder =
63-
clientSupportsSnippets
64-
? formatLSPPlaceholder(displayName, number: number)
65-
: ""
66-
if placeholders.isEmpty {
67-
result += placeholder
68-
} else {
69-
placeholders.latest.contents += placeholder
70-
}
71-
}
72-
}
73-
74-
return result
75-
}
76-
77-
/// Scan `input` to identify special elements within: curly braces, which may
78-
/// need to be escaped; and SourceKit placeholder open/close delimiters.
79-
private func tokenize(_ input: String) -> [SnippetToken] {
80-
var index = input.startIndex
81-
var isAtEnd: Bool { index == input.endIndex }
82-
func match(_ char: Character) -> Bool {
83-
if isAtEnd || input[index] != char {
84-
return false
85-
} else {
86-
input.formIndex(after: &index)
87-
return true
17+
func rewriteSourceKitPlaceholders(in string: String, clientSupportsSnippets: Bool) -> String {
18+
var result = string
19+
var index = 1
20+
while let start = result.range(of: "<#") {
21+
guard let end = result[start.upperBound...].range(of: "#>") else {
22+
logger.fault("Invalid placeholder in \(string)")
23+
return string
8824
}
89-
}
90-
func next() -> Character? {
91-
guard !isAtEnd else { return nil }
92-
defer { input.formIndex(after: &index) }
93-
return input[index]
94-
}
95-
96-
var tokens: [SnippetToken] = []
97-
var text = ""
98-
while let char = next() {
99-
switch char {
100-
case "<":
101-
if match("#") {
102-
tokens.append(.text(text))
103-
text.removeAll()
104-
tokens.append(.placeholderOpen)
105-
} else {
106-
text.append(char)
107-
}
108-
109-
case "#":
110-
if match(">") {
111-
tokens.append(.text(text))
112-
text.removeAll()
113-
tokens.append(.placeholderClose)
114-
} else {
115-
text.append(char)
116-
}
117-
118-
case "{", "}":
119-
tokens.append(.text(text))
120-
text.removeAll()
121-
tokens.append(.curlyBrace(char))
122-
123-
case let c:
124-
text.append(c)
25+
let rawPlaceholder = String(result[start.lowerBound..<end.upperBound])
26+
guard let displayName = nameForSnippet(rawPlaceholder) else {
27+
logger.fault("Failed to decode placeholder \(rawPlaceholder) in \(string)")
28+
return string
12529
}
30+
let snippet = clientSupportsSnippets ? "${\(index):\(displayName)}" : ""
31+
result.replaceSubrange(start.lowerBound..<end.upperBound, with: snippet)
32+
index += 1
12633
}
127-
128-
tokens.append(.text(text))
129-
130-
return tokens
131-
}
132-
133-
/// A syntactical element inside a SourceKit snippet.
134-
private enum SnippetToken {
135-
/// A placeholder delimiter.
136-
case placeholderOpen, placeholderClose
137-
/// One of '{' or '}', which may need to be escaped in the output.
138-
case curlyBrace(Character)
139-
/// Any other consecutive run of characters from the input, which needs no
140-
/// special treatment.
141-
case text(String)
34+
return result
14235
}
14336

144-
/// Given the interior text of a SourceKit placeholder, extract a display name
145-
/// suitable for a LSP snippet.
146-
private func nameForSnippet(_ body: String) -> String? {
147-
var text = rewrappedAsPlaceholder(body)
37+
/// Parse a SourceKit placeholder and extract the display name suitable for a
38+
/// LSP snippet.
39+
fileprivate func nameForSnippet(_ text: String) -> String? {
40+
var text = text
14841
return text.withSyntaxText {
14942
guard let data = RawEditorPlaceholderData(syntaxText: $0) else {
15043
return nil
15144
}
15245
return String(syntaxText: data.typeForExpansionText ?? data.displayText)
15346
}
15447
}
155-
156-
private let placeholderStart = "<#"
157-
private let placeholderEnd = "#>"
158-
private func rewrappedAsPlaceholder(_ body: String) -> String {
159-
return placeholderStart + body + placeholderEnd
160-
}
161-
162-
/// Wrap `body` in LSP snippet placeholder syntax, using `number` as the
163-
/// placeholder's index in the snippet.
164-
private func formatLSPPlaceholder(_ body: String, number: Int) -> String {
165-
"${\(number):\(body)}"
166-
}
167-
168-
private extension Array {
169-
/// Mutable access to the final element of an array.
170-
///
171-
/// - precondition: The array must not be empty.
172-
var latest: Element {
173-
get { self.last! }
174-
_modify {
175-
let index = self.index(before: self.endIndex)
176-
yield &self[index]
177-
}
178-
}
179-
}

0 commit comments

Comments
 (0)