sourcekit-lsp icon indicating copy to clipboard operation
sourcekit-lsp copied to clipboard

Add a syntactic "Add Codable structs from JSON" code action

Open DougGregor opened this issue 1 year ago • 8 comments

Add a syntactic action that takes JSON pasted into a Swift file or placed in a string literal, then turns it into a set of Codable structs that can represent the JSON. Our typical example starts like this:

{
    "name": "Produce",
    "shelves": [
        {
            "name": "Discount Produce",
            "product": {
                "name": "Banana",
                "points": 200,
                "description": "A banana that's perfectly ripe."
            }
        }
    ]
}

and turns into this:

struct JSONValue: Codable {
    var name: String
    var shelves: [Shelves]

    struct Shelves: Codable {
        var name: String
        var product: Product

        struct Product: Codable {
            var description: String
            var name: String
            var points: Double
        }
    }
}

This code action can definitely be improved by doing more work in analyzing the JSON to (for example) abstract over multiple elements in an array to make fields optional (if they only show up in some members) and perhaps even identify when we really have something that's an enum. Such improvements can be done without changing the general shape of this refactor.

The refactoring itself would live down in the swift-syntax package if not for its dependency on Foundation. We'll move as appropriate.

DougGregor avatar Apr 26 '24 00:04 DougGregor

@swift-ci please test

DougGregor avatar Apr 26 '24 00:04 DougGregor

@swift-ci please test

DougGregor avatar Apr 26 '24 01:04 DougGregor

@swift-ci please test

DougGregor avatar Apr 26 '24 01:04 DougGregor

@swift-ci please test

DougGregor avatar Apr 26 '24 02:04 DougGregor

@swift-ci please test Windows

DougGregor avatar Apr 26 '24 02:04 DougGregor

@swift-ci please test Windows

DougGregor avatar Apr 26 '24 02:04 DougGregor

@swift-ci please test Linux

DougGregor avatar Apr 26 '24 15:04 DougGregor

@swift-ci please test Linux

DougGregor avatar Apr 26 '24 17:04 DougGregor

@swift-ci please test

DougGregor avatar May 06 '24 20:05 DougGregor

@swift-ci please test Windows

DougGregor avatar May 06 '24 20:05 DougGregor

I just went ahead and rewrote this with a completely new structure that does merging of like elements in the whole tree. When merging a field w/ a missing value (or one explicitly marked null), we introduce an optional in Swift. This also handles Boolean values specially.

DougGregor avatar May 06 '24 21:05 DougGregor

@swift-ci please test

DougGregor avatar May 06 '24 21:05 DougGregor

@swift-ci please test Windows

DougGregor avatar May 06 '24 21:05 DougGregor

@swift-ci please test

DougGregor avatar May 07 '24 00:05 DougGregor

@swift-ci please test Windows

DougGregor avatar May 07 '24 00:05 DougGregor