<commit_before>//
//  File+Cache.swift
//  SwiftLint
//
//  Created by <NAME> on 2015-05-26.
//  Copyright (c) 2015 Realm. All rights reserved.
//

import Foundation
import SourceKittenFramework

private var responseCache = Cache({file -> [String: SourceKitRepresentable]? in
    do {
        return try Request.EditorOpen(file).failableSend()
    } catch let error as Request.Error {
        queuedPrintError(error.description)
        return nil
    } catch {
        return nil
    }
})
private var structureCache = Cache({file -> Structure? in
    if let structure = responseCache.get(file).map(Structure.init) {
        queueForRebuild.append(structure)
        return structure
    }
    return nil
})
private var syntaxMapCache = Cache({file in responseCache.get(file).map(SyntaxMap.init)})
private var syntaxKindsByLinesCache = Cache({file in file.syntaxKindsByLine()})

private var _allDeclarationsByType = [String: [String]]()
private var queueForRebuild = [Structure]()

private struct Cache<T> {

    private var values = [String: T]()
    private var factory: File -> T

    private init(_ factory: File -> T) {
        self.factory = factory
    }

    private mutating func get(file: File) -> T {
        let key = file.cacheKey
        if let value = values[key] {
            return value
        }
        let value = factory(file)
        values[key] = value
        return value
    }

    private mutating func invalidate(file: File) {
        if let key = file.path {
            values.removeValueForKey(key)
        }
    }

    private mutating func clear() {
        values.removeAll(keepCapacity: false)
    }
}

extension File {

    private var cacheKey: String {
        return path ?? "\(ObjectIdentifier(self).hashValue)"
    }

    public var sourcekitdFailed: Bool {
        return responseCache.get(self) == nil
    }

    internal var structure: Structure {
        guard let structure = structureCache.get(self) else {
            fatalError("Never call this for file that sourcekitd fails.")
        }
        return structure
    }

    internal var syntaxMap: SyntaxMap {<commit_msg>Change `File.sourcekitdFailed` to settable and internal<commit_after>//
//  File+Cache.swift
//  SwiftLint
//
//  Created by <NAME> on 2015-05-26.
//  Copyright (c) 2015 Realm. All rights reserved.
//

import Foundation
import SourceKittenFramework

private var responseCache = Cache({file -> [String: SourceKitRepresentable]? in
    do {
        return try Request.EditorOpen(file).failableSend()
    } catch let error as Request.Error {
        queuedPrintError(error.description)
        return nil
    } catch {
        return nil
    }
})
private var structureCache = Cache({file -> Structure? in
    if let structure = responseCache.get(file).map(Structure.init) {
        queueForRebuild.append(structure)
        return structure
    }
    return nil
})
private var syntaxMapCache = Cache({file in responseCache.get(file).map(SyntaxMap.init)})
private var syntaxKindsByLinesCache = Cache({file in file.syntaxKindsByLine()})

private var _allDeclarationsByType = [String: [String]]()
private var queueForRebuild = [Structure]()

private struct Cache<T> {

    private var values = [String: T]()
    private var factory: File -> T

    private init(_ factory: File -> T) {
        self.factory = factory
    }

    private mutating func get(file: File) -> T {
        let key = file.cacheKey
        if let value = values[key] {
            return value
        }
        let value = factory(file)
        values[key] = value
        return value
    }

    private mutating func invalidate(file: File) {
        if let key = file.path {
            values.removeValueForKey(key)
        }
    }

    private mutating func clear() {
        values.removeAll(keepCapacity: false)
    }
}

extension File {

    private var cacheKey: String {
        return path ?? "\(ObjectIdentifier(self).hashValue)"
    }

    internal var sourcekitdFailed: Bool {
        get {
            return responseCache.get(self) == nil
        }
        set {
            if newValue {
                responseCache.values[cacheKey] = Optional<[String: SourceKitRepresentable]>.None
            } else {
                responseCache.values.removeValueForKey(cacheKey)
            }
        }
    }

    internal var structure: Structure {
        guard let structure = structureCache.get(self) else {
            fatalError("Never call this for file that sourcekitd fails.")
        }
        return structure
    }

    internal var syntaxMap: SyntaxMap {
{'fraction_non_alphanumeric': 0.09704271631982475, 'fraction_numerical': 0.005257393209200438, 'mean_word_length': 2.425356339084771, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 18, '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': '6340927', 'n_tokens_mistral': 1309, 'n_tokens_neox': 1253, 'n_words': 362}