import Foundation import ProjectSpec import XcodeProj public class BreakpointGenerator { let project: Project public init(project: Project) { self.project = project } func generateBreakpointList() throws -> XCBreakpointList? { let breakpoints = project.breakpoints guard !breakpoints.isEmpty else { return nil } return XCBreakpointList(type: "4", version: "2.0", breakpoints: try breakpoints.map({ try generateBreakpointProxy($0) })) } private func generateBreakpointProxy(_ breakpoint: Breakpoint) throws -> XCBreakpointList.BreakpointProxy { let breakpointExtensionID: BreakpointExtensionID var filePath: String? var line: String? var column: String? var scope: String? var stopOnStyle: String? var symbol: String? var module: String? switch breakpoint.type { case let .file(path, lineNumber, columnNumber): breakpointExtensionID = .file filePath = path line = String(lineNumber) column = columnNumber.map(String.init) case let .exception(exception): breakpointExtensionID = .exception scope = exception.scope.rawValue stopOnStyle = exception.stopOnStyle.rawValue case .swiftError: breakpointExtensionID = .swiftError case .openGLError: breakpointExtensionID = .openGLError case let .symbolic(symbolName, moduleName): breakpointExtensionID = .symbolic symbol = symbolName module = moduleName case .ideConstraintError: breakpointExtensionID = .ideConstraintError case .ideTestFailure: breakpointExtensionID = .ideTestFailure case .runtimeIssue: breakpointExtensionID = .runtimeIssue } let xcbreakpoint = XCBreakpointList.BreakpointProxy.BreakpointContent( enabled: breakpoint.enabled, ignoreCount: String(breakpoint.ignoreCount), continueAfterRunningActions: breakpoint.continueAfterRunningActions, filePath: filePath, startingColumn: column, endingColumn: column, startingLine: line, endingLine: line, symbol: symbol, module: module, scope: scope, stopOnStyle: stopOnStyle, condition: breakpoint.condition, actions: try breakpoint.actions.map { try generateBreakpointActionProxy($0) } ) return XCBreakpointList.BreakpointProxy( breakpointExtensionID: breakpointExtensionID, breakpointContent: xcbreakpoint ) } private func generateBreakpointActionProxy(_ breakpointAction: Breakpoint.Action) throws -> XCBreakpointList.BreakpointProxy.BreakpointContent.BreakpointActionProxy { let actionExtensionID: BreakpointActionExtensionID var consoleCommand: String? var message: String? var conveyanceType: String? var command: String? var arguments: String? var waitUntilDone: Bool? var script: String? var soundName: String? switch breakpointAction { case let .debuggerCommand(command): actionExtensionID = .debuggerCommand consoleCommand = command case let .log(log): actionExtensionID = .log message = log.message conveyanceType = log.conveyanceType.rawValue case let .shellCommand(commandPath, commandArguments, waitUntilCommandDone): actionExtensionID = .shellCommand command = commandPath arguments = commandArguments waitUntilDone = waitUntilCommandDone case .graphicsTrace: actionExtensionID = .graphicsTrace case let .appleScript(appleScript): actionExtensionID = .appleScript script = appleScript case let .sound(sound): actionExtensionID = .sound soundName = sound.rawValue } let xcaction = XCBreakpointList.BreakpointProxy.BreakpointContent.BreakpointActionProxy.ActionContent( consoleCommand: consoleCommand, message: message, conveyanceType: conveyanceType, command: command, arguments: arguments, waitUntilDone: waitUntilDone, script: script, soundName: soundName ) return XCBreakpointList.BreakpointProxy.BreakpointContent.BreakpointActionProxy( actionExtensionID: actionExtensionID, actionContent: xcaction ) } }