From b36849345bb0032c5d9f9a7d8f6b27dd95f04840 Mon Sep 17 00:00:00 2001 From: Rauhul Varma Date: Mon, 19 Aug 2024 11:27:38 -0700 Subject: [PATCH] Improve SVD2SwiftPlugin errors Updates the SVD2SwiftPlugin to format JSON decoding errors into human readable strings. --- Plugins/SVD2SwiftPlugin/SVD2SwiftPlugin.swift | 11 +++- ...wiftPluginConfigurationDecodingError.swift | 61 +++++++++++++++++++ Tests/SVD2SwiftPluginTests/svd2swift.json | 2 +- 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 Plugins/SVD2SwiftPlugin/SVD2SwiftPluginConfigurationDecodingError.swift diff --git a/Plugins/SVD2SwiftPlugin/SVD2SwiftPlugin.swift b/Plugins/SVD2SwiftPlugin/SVD2SwiftPlugin.swift index 8f0a90a0..b0822da4 100644 --- a/Plugins/SVD2SwiftPlugin/SVD2SwiftPlugin.swift +++ b/Plugins/SVD2SwiftPlugin/SVD2SwiftPlugin.swift @@ -30,8 +30,15 @@ struct SVD2SwiftPlugin: BuildToolPlugin { // Load the list of peripherals to generate from the config file. let pluginConfigURL = URL(fileURLWithPath: pluginConfigFile.string) let pluginConfigData = try Data(contentsOf: pluginConfigURL) - let pluginConfig = try JSONDecoder() - .decode(SVD2SwiftPluginConfiguration.self, from: pluginConfigData) + let pluginConfig: SVD2SwiftPluginConfiguration + do { + pluginConfig = try JSONDecoder() + .decode(SVD2SwiftPluginConfiguration.self, from: pluginConfigData) + } catch let error as DecodingError { + throw SVD2SwiftPluginConfigurationDecodingError( + url: pluginConfigURL, + error: error) + } guard !pluginConfig.peripherals.isEmpty else { throw SVD2SwiftPluginError.missingPeripherals(target, pluginConfigFile) } diff --git a/Plugins/SVD2SwiftPlugin/SVD2SwiftPluginConfigurationDecodingError.swift b/Plugins/SVD2SwiftPlugin/SVD2SwiftPluginConfigurationDecodingError.swift new file mode 100644 index 00000000..943bfce0 --- /dev/null +++ b/Plugins/SVD2SwiftPlugin/SVD2SwiftPluginConfigurationDecodingError.swift @@ -0,0 +1,61 @@ +//===----------------------------------------------------------*- swift -*-===// +// +// This source file is part of the Swift MMIO open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +import Foundation + +struct SVD2SwiftPluginConfigurationDecodingError { + var description: String +} + +extension SVD2SwiftPluginConfigurationDecodingError: CustomStringConvertible { + init(url: URL, error: DecodingError) { + func format(_ codingPath: [any CodingKey]) -> String{ + if codingPath.isEmpty { + return "" + } else { + var path = "" + for key in codingPath { + if !path.isEmpty { + path.append(".") + } + if let index = key.intValue { + path.append("[") + path.append("\(index)") + path.append("]") + } else { + path.append(key.stringValue) + } + } + return path + } + } + + let errorFragment = switch error { + case let .typeMismatch(type, context): + "Expected type \"\(type)\" at path \"\(format(context.codingPath))\"." + case let .valueNotFound(_, context): + "Expected value at path \"\(format(context.codingPath))\"." + case let .keyNotFound(key, context): + "Expected key at path \"\(format(context.codingPath + [key]))\"." + case let .dataCorrupted(context): + "Data corrupted at path \"\(format(context.codingPath))\"." + default: + "Unknown decoding error: \(error)" + } + self.description = """ + \(url.path):1:1: \ + Failed to read \(FileKind.svd2swift): \ + \(errorFragment) + """ + } +} + +extension SVD2SwiftPluginConfigurationDecodingError: Error {} diff --git a/Tests/SVD2SwiftPluginTests/svd2swift.json b/Tests/SVD2SwiftPluginTests/svd2swift.json index 7b6a0bda..609271d1 100644 --- a/Tests/SVD2SwiftPluginTests/svd2swift.json +++ b/Tests/SVD2SwiftPluginTests/svd2swift.json @@ -3,7 +3,7 @@ "TIMER0", "TIMER1", ], - "indentation-width": 2, + "indentation-width": 1, "namespace-under-device": true, "instance-member-peripherals": false, "device-name": "Banana"