mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This patch provides an API and Serialization for clang-style diagnostics from within Swift. Libraries can use this API to pop their own custom diagnostics that can be serialized to JSON.
79 lines
2.7 KiB
Swift
79 lines
2.7 KiB
Swift
//===--- JSONDiagnosticConsumer.swift - JSON Serializer for Diagnostics ---===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 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
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
// This file provides a JSON serializer for compiler diagnostics emitted using
|
|
// the DiagnosticEngine.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import Foundation
|
|
|
|
public final class JSONDiagnosticConsumer: DiagnosticConsumer {
|
|
/// Enumerates the possible places this consumer might output diagnostics.
|
|
private enum OutputFormat {
|
|
case url(URL)
|
|
case stdout
|
|
}
|
|
|
|
/// The current set of diagnostics that have been emitted.
|
|
private var diagnostics = [Diagnostic]()
|
|
|
|
/// The output format this consumer will output the generated JSON to.
|
|
private let outputFormat: OutputFormat
|
|
|
|
/// Creates a JSONDiagnosticConsumer that will output the generated JSON
|
|
/// to a file at the given URL.
|
|
/// - parameter outputURL: The URL that the consumer will write JSON
|
|
/// diagnostics to.
|
|
/// - note: If a file exists at the URL already, it will be overwritten.
|
|
public init(outputURL: URL) {
|
|
self.outputFormat = .url(outputURL)
|
|
}
|
|
|
|
/// Creates a JSONDiagnosticConsumer that will output the generated JSON
|
|
/// to standard output.
|
|
public init() {
|
|
self.outputFormat = .stdout
|
|
}
|
|
|
|
/// Adds the diagnostic to the list of registered diagnostics.
|
|
public func handle(_ diagnostic: Diagnostic) {
|
|
self.diagnostics.append(diagnostic)
|
|
}
|
|
|
|
/// Writes the contents of the diagnostics as JSON out to the specified
|
|
/// output location.
|
|
public func finalize() {
|
|
do {
|
|
let encoder = JSONEncoder()
|
|
encoder.outputFormatting = .prettyPrinted
|
|
let data = try encoder.encode(diagnostics)
|
|
switch outputFormat {
|
|
case .url(let url):
|
|
if FileManager.default.fileExists(atPath: url.path) {
|
|
try FileManager.default.removeItem(at: url)
|
|
}
|
|
FileManager.default.createFile(atPath: url.path, contents: data)
|
|
case .stdout:
|
|
FileHandle.standardOutput.write(data)
|
|
}
|
|
} catch {
|
|
let dummyEngine = DiagnosticEngine()
|
|
let printingConsumer = PrintingDiagnosticConsumer()
|
|
dummyEngine.addConsumer(printingConsumer)
|
|
dummyEngine.diagnose(.couldNotOutputJSON)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Diagnostic.Message {
|
|
static let couldNotOutputJSON =
|
|
Diagnostic.Message(.error, "failed emitting JSON diagnostics")
|
|
} |