diff --git a/Sources/SwiftSyntax/RawSyntax.swift b/Sources/SwiftSyntax/RawSyntax.swift index 1af1c5d4a13..c771ee14b2d 100644 --- a/Sources/SwiftSyntax/RawSyntax.swift +++ b/Sources/SwiftSyntax/RawSyntax.swift @@ -85,7 +85,7 @@ fileprivate enum RawSyntaxData { /// Represents the raw tree structure underlying the syntax tree. These nodes /// have no notion of identity and only provide structure to the tree. They /// are immutable and can be freely shared between syntax nodes. -struct RawSyntax: Codable { +struct RawSyntax { fileprivate let data: RawSyntaxData let presence: SourcePresence @@ -198,61 +198,6 @@ struct RawSyntax: Codable { case nodeLookupFailed(SyntaxNodeId) } - /// Creates a RawSyntax from the provided Foundation Decoder. - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let id = try container.decodeIfPresent(SyntaxNodeId.self, forKey: .id) - let omitted = try container.decodeIfPresent(Bool.self, forKey: .omitted) ?? false - - if omitted { - guard let id = id else { - throw IncrementalDecodingError.omittedNodeHasNoId - } - guard let lookupFunc = decoder.userInfo[.omittedNodeLookupFunction] as? - (SyntaxNodeId) -> RawSyntax? else { - throw IncrementalDecodingError.noLookupFunctionPassed - } - guard let lookupNode = lookupFunc(id) else { - throw IncrementalDecodingError.nodeLookupFailed(id) - } - self = lookupNode - return - } - - let presence = try container.decode(SourcePresence.self, forKey: .presence) - if let kind = try container.decodeIfPresent(SyntaxKind.self, forKey: .kind) { - let layout = try container.decode([RawSyntax?].self, forKey: .layout) - self.init(kind: kind, layout: layout, presence: presence, id: id) - } else { - let kind = try container.decode(TokenKind.self, forKey: .tokenKind) - let leadingTrivia = try container.decode(Trivia.self, forKey: .leadingTrivia) - let trailingTrivia = try container.decode(Trivia.self, forKey: .trailingTrivia) - self.init(kind: kind, leadingTrivia: leadingTrivia, - trailingTrivia: trailingTrivia, presence: presence, id: id) - } - if let callback = decoder.userInfo[.rawSyntaxDecodedCallback] as? - (RawSyntax) -> Void { - callback(self) - } - } - - /// Encodes the RawSyntax to the provided Foundation Encoder. - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - switch self.data { - case let .node(kind, layout): - try container.encode(id, forKey: .id) - try container.encode(kind, forKey: .kind) - try container.encode(layout, forKey: .layout) - case let .token(kind, leadingTrivia, trailingTrivia): - try container.encode(id, forKey: .id) - try container.encode(kind, forKey: .tokenKind) - try container.encode(leadingTrivia, forKey: .leadingTrivia) - try container.encode(trailingTrivia, forKey: .trailingTrivia) - } - try container.encode(presence, forKey: .presence) - } - /// Creates a RawSyntax node that's marked missing in the source with the /// provided kind and layout. /// - Parameters: @@ -389,6 +334,63 @@ extension RawSyntax { } } +extension RawSyntax: Codable { + /// Creates a RawSyntax from the provided Foundation Decoder. + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let id = try container.decodeIfPresent(SyntaxNodeId.self, forKey: .id) + let omitted = try container.decodeIfPresent(Bool.self, forKey: .omitted) ?? false + + if omitted { + guard let id = id else { + throw IncrementalDecodingError.omittedNodeHasNoId + } + guard let lookupFunc = decoder.userInfo[.omittedNodeLookupFunction] as? + (SyntaxNodeId) -> RawSyntax? else { + throw IncrementalDecodingError.noLookupFunctionPassed + } + guard let lookupNode = lookupFunc(id) else { + throw IncrementalDecodingError.nodeLookupFailed(id) + } + self = lookupNode + return + } + + let presence = try container.decode(SourcePresence.self, forKey: .presence) + if let kind = try container.decodeIfPresent(SyntaxKind.self, forKey: .kind) { + let layout = try container.decode([RawSyntax?].self, forKey: .layout) + self.init(kind: kind, layout: layout, presence: presence, id: id) + } else { + let kind = try container.decode(TokenKind.self, forKey: .tokenKind) + let leadingTrivia = try container.decode(Trivia.self, forKey: .leadingTrivia) + let trailingTrivia = try container.decode(Trivia.self, forKey: .trailingTrivia) + self.init(kind: kind, leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia, presence: presence, id: id) + } + if let callback = decoder.userInfo[.rawSyntaxDecodedCallback] as? + (RawSyntax) -> Void { + callback(self) + } + } + + /// Encodes the RawSyntax to the provided Foundation Encoder. + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + switch self.data { + case let .node(kind, layout): + try container.encode(id, forKey: .id) + try container.encode(kind, forKey: .kind) + try container.encode(layout, forKey: .layout) + case let .token(kind, leadingTrivia, trailingTrivia): + try container.encode(id, forKey: .id) + try container.encode(kind, forKey: .tokenKind) + try container.encode(leadingTrivia, forKey: .leadingTrivia) + try container.encode(trailingTrivia, forKey: .trailingTrivia) + } + try container.encode(presence, forKey: .presence) + } +} + extension RawSyntax: ByteTreeObjectDecodable { enum SyntaxType: UInt8, ByteTreeScalarDecodable { case token = 0