mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-06 18:24:36 +01:00
Fix JSON base indentation in Create Codable structs
Signed-off-by: Karan <karanlokchandani@protonmail.com>
This commit is contained in:
@@ -99,18 +99,36 @@ package struct ConvertJSONToCodableStruct: EditRefactoringProvider {
|
||||
let topLevelObject = JSONObject(dictionary: dictionary)
|
||||
|
||||
// Render the top-level object as a struct.
|
||||
let indentation = BasicFormat.inferIndentation(of: syntax)
|
||||
let inferenceNode: Syntax
|
||||
switch preflight {
|
||||
case .closure(let closure): inferenceNode = Syntax(closure)
|
||||
case .endingClosure(let closure, _): inferenceNode = Syntax(closure)
|
||||
case .stringLiteral(let literal, _): inferenceNode = Syntax(literal)
|
||||
}
|
||||
let indentation = BasicFormat.inferIndentation(of: inferenceNode)
|
||||
let format = BasicFormat(indentationWidth: indentation)
|
||||
let decls = topLevelObject.asDeclSyntax(name: "JSONValue")
|
||||
.formatted(using: format)
|
||||
|
||||
// Apply base indentation to the generated struct.
|
||||
// The first line inherits the existing indentation from the source file.
|
||||
// Subsequent lines need to be explicitly indented.
|
||||
let baseIndentation = getBaseIndentation(from: inferenceNode)
|
||||
let indentedDecls = decls.description.split(separator: "\n", omittingEmptySubsequences: false)
|
||||
.enumerated()
|
||||
.map { (index, line) in
|
||||
if index == 0 { return String(line) }
|
||||
return baseIndentation.description + line
|
||||
}
|
||||
.joined(separator: "\n")
|
||||
|
||||
// Render the change into a set of source edits.
|
||||
switch preflight {
|
||||
case .closure(let closure):
|
||||
// Closures are replaced entirely, since they were invalid code to
|
||||
// start with.
|
||||
return [
|
||||
SourceEdit(range: closure.trimmedRange, replacement: decls.description)
|
||||
SourceEdit(range: closure.trimmedRange, replacement: indentedDecls)
|
||||
]
|
||||
case .endingClosure(let closure, let unexpected):
|
||||
// Closures are replaced entirely, since they were invalid code to
|
||||
@@ -118,7 +136,7 @@ package struct ConvertJSONToCodableStruct: EditRefactoringProvider {
|
||||
return [
|
||||
SourceEdit(
|
||||
range: closure.positionAfterSkippingLeadingTrivia..<unexpected.endPosition,
|
||||
replacement: decls.description
|
||||
replacement: indentedDecls
|
||||
)
|
||||
]
|
||||
case .stringLiteral(let literal, _):
|
||||
@@ -127,12 +145,23 @@ package struct ConvertJSONToCodableStruct: EditRefactoringProvider {
|
||||
return [
|
||||
SourceEdit(
|
||||
range: literal.endPosition..<literal.endPosition,
|
||||
replacement: "\n" + decls.description
|
||||
replacement: "\n" + indentedDecls
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the indentation of the given node from the source file.
|
||||
private static func getBaseIndentation(from node: Syntax) -> Trivia {
|
||||
guard let startToken = node.firstToken(viewMode: .sourceAccurate) else { return [] }
|
||||
var indentationPieces: [TriviaPiece] = []
|
||||
for piece in startToken.leadingTrivia.reversed() {
|
||||
if case .newlines = piece { break }
|
||||
indentationPieces.append(piece)
|
||||
}
|
||||
return Trivia(pieces: indentationPieces.reversed())
|
||||
}
|
||||
|
||||
/// The result of preflighting a syntax node to try to find potential JSON
|
||||
/// in it.
|
||||
private enum Preflight {
|
||||
@@ -271,7 +300,7 @@ private struct JSONObject {
|
||||
|
||||
return """
|
||||
struct \(raw: name): Codable {
|
||||
\(members.trimmed)
|
||||
\(members.trimmed)
|
||||
}
|
||||
"""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user