<commit_before>//
//  CommandArguments.swift
//  Example
//
//  Created by <NAME> on 3/7/15.
//  Copyright (c) 2015 jakeheis. All rights reserved.
//

public class CommandArguments {
    
    var keyedArguments: [String: AnyObject]
    
    init() {
        self.keyedArguments = [:]
    }
    
    init(keyedArguments: [String: AnyObject]) {
        self.keyedArguments = keyedArguments
    }
    
    init(rawArguments: RawArguments, signature: CommandSignature) {
        self.keyedArguments = [:]
    }
    
    // Keying arguments
    
    class func fromRawArguments(rawArguments: RawArguments, signature: CommandSignature) throws -> CommandArguments {
        if signature.isEmpty {
            return try handleEmptySignature(rawArguments: rawArguments)
        }
        
        let arguments = rawArguments.unclassifiedArguments()
        
        if arguments.count < signature.requiredParameters.count {
            throw CLIError.Error(errorMessage(expectedCount: signature.requiredParameters.count, givenCount: arguments.count))
        }
        
        if !signature.collectRemainingArguments && signature.optionalParameters.isEmpty && arguments.count != signature.requiredParameters.count {
            throw CLIError.Error(errorMessage(expectedCount: signature.requiredParameters.count, givenCount: arguments.count))
        }
        
        if !signature.collectRemainingArguments && arguments.count > signature.requiredParameters.count + signature.optionalParameters.count {
            throw CLIError.Error(errorMessage(expectedCount: signature.requiredParameters.count + signature.optionalParameters.count, givenCount: arguments.count))
        }
        
        let commandArguments = CommandArguments()
        
        // First handle required arguments
        for i in 0..<signature.requiredParameters.count {
            let parameter = signature.requiredParameters[i]
            let value = arguments[i]
            commandArguments[parameter] = value
        }
        
        // Then handle optional arguments if there are any
        if !signature.optionalParameters.isEmpty && arguments.count > signature.requiredParameters.count {
            for i in 0..<signature.optionalParameters.count {
                let index = i + signature.requiredParameters.count
                if index >= arguments.count {
                    break
                }
                let parameter = signature.optionalParameters[i]
                let value = arguments[index]
                commandArguments[parameter] = value
            }
        }
        
        // Finally collect the remaining arguments into an array if ... is present
        if signature.collectRemainingArguments {
            let parameter = signature.optionalParameters.isEmpty ? signature.requiredParameters[signature.requiredParameters.count-1] : signature.optionalParameters[signature.optionalParameters.count-1]

            var collectedArgument = [commandArguments.requiredArgument(parameter)]
            
            let startingIndex = signature.requiredParameters.count + signature.optionalParameters.count
            for i in startingIndex..<arguments.count {
                collectedArgument.append(arguments[i])
            }
            
            commandArguments[parameter] = collectedArgument
        }
        
        return commandArguments
    }
    
    private class func handleEmptySignature(rawArguments rawArguments: RawArguments) throws -> CommandArguments {
        guard rawArguments.unclassifiedArguments().count == 0  else {
            throw CLIError.Error("Expected no arguments, got \(rawArguments.unclassifiedArguments().count).")
        }
    
        return CommandArguments()
    }
    
    private class func errorMessage(expectedCount expectedCount: Int, givenCount: Int) -> String {
        let argString = expectedCount == 1 ? "argument" : "arguments"
        return "Expected \(expectedCount) \(argString), but got \(givenCount)."
    }
    
    // MARK: - Subscripting
    
    /**
        Generic subscripting of arguments
    
        - SeeAlso: Typesafe shortcuts such as `args.requiredArguments("arg")`
    */
    public subscript(key: String) -> AnyObject? {
        get {
            return keyedArguments[key]
        }
        set(newArgument) {
            keyedArguments[key] = newArgument
        }
    }
    
    // MARK: - Typesafe shortcuts
    
    /**
        Subscripting shortcut for arguments guaranteed to be present. Only use for arguments
        in the command signature of the form `<requiredArgument>`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func requiredArgument(key: String) -> String {
        return optionalArgument(key)!
    }
    
    /**
        Subscripting shortcut for arguments sometimes present. Only use for arguments
        in the command signature of the form `[<optionalArgument>]`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func optionalArgument(key: String) -> String? {
        if let arg = keyedArguments[key] as? String {
            return arg
        }
        return nil
    }
    
    /**
        Subscripting shortcut for a collected argument guaranteed to be present. Only use
        for arguments in the command signature of the form `<requiredArgument> ...`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func requiredCollectedArgument(key: String) -> [String] {
        return optionalCollectedArgument(key)!
    }
    
    /**
        Subscripting shortcut for a collected argument sometimes present. Only use
        for arguments in the command signature of the form `[<optionalArgument>] ...`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func optionalCollectedArgument(key: String) -> [String]? {
        if let arg = keyedArguments[key] as? [String] {
            return arg
        }
        return nil
    }
    
}
<commit_msg>Fixing empty optional collected argument crash<commit_after>//
//  CommandArguments.swift
//  Example
//
//  Created by <NAME> on 3/7/15.
//  Copyright (c) 2015 jakeheis. All rights reserved.
//

public class CommandArguments {
    
    var keyedArguments: [String: AnyObject]
    
    init() {
        self.keyedArguments = [:]
    }
    
    init(keyedArguments: [String: AnyObject]) {
        self.keyedArguments = keyedArguments
    }
    
    init(rawArguments: RawArguments, signature: CommandSignature) {
        self.keyedArguments = [:]
    }
    
    // Keying arguments
    
    class func fromRawArguments(rawArguments: RawArguments, signature: CommandSignature) throws -> CommandArguments {
        if signature.isEmpty {
            return try handleEmptySignature(rawArguments: rawArguments)
        }
        
        let arguments = rawArguments.unclassifiedArguments()
        
        if arguments.count < signature.requiredParameters.count {
            throw CLIError.Error(errorMessage(expectedCount: signature.requiredParameters.count, givenCount: arguments.count))
        }
        
        if !signature.collectRemainingArguments && signature.optionalParameters.isEmpty && arguments.count != signature.requiredParameters.count {
            throw CLIError.Error(errorMessage(expectedCount: signature.requiredParameters.count, givenCount: arguments.count))
        }
        
        if !signature.collectRemainingArguments && arguments.count > signature.requiredParameters.count + signature.optionalParameters.count {
            throw CLIError.Error(errorMessage(expectedCount: signature.requiredParameters.count + signature.optionalParameters.count, givenCount: arguments.count))
        }
        
        let commandArguments = CommandArguments()
        
        // First handle required arguments
        for i in 0..<signature.requiredParameters.count {
            let parameter = signature.requiredParameters[i]
            let value = arguments[i]
            commandArguments[parameter] = value
        }
        
        // Then handle optional arguments if there are any
        if !signature.optionalParameters.isEmpty && arguments.count > signature.requiredParameters.count {
            for i in 0..<signature.optionalParameters.count {
                let index = i + signature.requiredParameters.count
                if index >= arguments.count {
                    break
                }
                let parameter = signature.optionalParameters[i]
                let value = arguments[index]
                commandArguments[parameter] = value
            }
        }
        
        // Finally collect the remaining arguments into an array if ... is present
        if signature.collectRemainingArguments {
            let parameter = signature.optionalParameters.isEmpty ? signature.requiredParameters[signature.requiredParameters.count-1] : signature.optionalParameters[signature.optionalParameters.count-1]

            if let singleArgument = commandArguments.optionalArgument(parameter) {
                var collectedArgument = [singleArgument]
                let startingIndex = signature.requiredParameters.count + signature.optionalParameters.count
                for i in startingIndex..<arguments.count {
                    collectedArgument.append(arguments[i])
                }
                commandArguments[parameter] = collectedArgument
            } else {
                commandArguments[parameter] = []
            }
        }
        
        return commandArguments
    }
    
    private class func handleEmptySignature(rawArguments rawArguments: RawArguments) throws -> CommandArguments {
        guard rawArguments.unclassifiedArguments().count == 0  else {
            throw CLIError.Error("Expected no arguments, got \(rawArguments.unclassifiedArguments().count).")
        }
    
        return CommandArguments()
    }
    
    private class func errorMessage(expectedCount expectedCount: Int, givenCount: Int) -> String {
        let argString = expectedCount == 1 ? "argument" : "arguments"
        return "Expected \(expectedCount) \(argString), but got \(givenCount)."
    }
    
    // MARK: - Subscripting
    
    /**
        Generic subscripting of arguments
    
        - SeeAlso: Typesafe shortcuts such as `args.requiredArguments("arg")`
    */
    public subscript(key: String) -> AnyObject? {
        get {
            return keyedArguments[key]
        }
        set(newArgument) {
            keyedArguments[key] = newArgument
        }
    }
    
    // MARK: - Typesafe shortcuts
    
    /**
        Subscripting shortcut for arguments guaranteed to be present. Only use for arguments
        in the command signature of the form `<requiredArgument>`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func requiredArgument(key: String) -> String {
        return optionalArgument(key)!
    }
    
    /**
        Subscripting shortcut for arguments sometimes present. Only use for arguments
        in the command signature of the form `[<optionalArgument>]`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func optionalArgument(key: String) -> String? {
        if let arg = keyedArguments[key] as? String {
            return arg
        }
        return nil
    }
    
    /**
        Subscripting shortcut for a collected argument guaranteed to be present. Only use
        for arguments in the command signature of the form `<requiredArgument> ...`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func requiredCollectedArgument(key: String) -> [String] {
        return optionalCollectedArgument(key)!
    }
    
    /**
        Subscripting shortcut for a collected argument sometimes present. Only use
        for arguments in the command signature of the form `[<optionalArgument>] ...`
    
        - Parameter key: the name of the argument as seen in the command signature
    */
    public func optionalCollectedArgument(key: String) -> [String]? {
        if let arg = keyedArguments[key] as? [String] {
            return arg
        }
        return nil
    }
    
}

{'fraction_non_alphanumeric': 0.07882809970864357, 'fraction_numerical': 0.0022661055357720947, 'mean_word_length': 2.242456048281291, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6486591', 'n_tokens_mistral': 2937, 'n_tokens_neox': 2842, 'n_words': 831}