Created
September 3, 2018 21:29
-
-
Save mackoj/33e611b7bf349d8b1f5e45574679ca1d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import Foundation | |
struct AllocDeallocTester { | |
struct AllocationResult : CustomDebugStringConvertible { | |
let className : String | |
var pointerNumber : Int = 0 | |
var numberOfMissDealloc : Int = 0 | |
var numberOfValidDealloc : Int = 0 | |
init(className inputClassName: String) { | |
self.className = inputClassName | |
} | |
var debugDescription: String { | |
get { | |
let state = numberOfMissDealloc == 0 ? "👍🏻" : "👎🏻" | |
return "\n\(state)\(className)[\(pointerNumber)] nonDealloc(\(numberOfMissDealloc)) Dealloc(\(numberOfValidDealloc))" | |
} | |
} | |
} | |
enum AllocType { | |
case alloc | |
case dealloc | |
} | |
struct LigneResult { | |
let className : String | |
let pointer : String | |
var type : AllocType = .alloc | |
} | |
static func matches(for regex: String, in text: String) -> [String] { | |
do { | |
let regex = try NSRegularExpression(pattern: regex) | |
let nsString = text as NSString | |
let range = NSRange(location: 0, length: nsString.length) | |
let results = regex.matches(in: text, options: [], range: range) | |
var output : [String] = [] | |
guard | |
let first = (results.first?.range(at: 1)), | |
let second = (results.first?.range(at: 2)), | |
let third = (results.first?.range(at: 3)) | |
else { return [] } | |
output.append(nsString.substring(with: first)) | |
output.append(nsString.substring(with: second)) | |
output.append(nsString.substring(with: third)) | |
return output | |
} catch let error { | |
print("invalid regex: \(error.localizedDescription)") | |
return [] | |
} | |
} | |
static func getLigneData(inputString : String) -> LigneResult? { | |
let regexPattern = "-- (alloc|dealloc) \\d+ -- @\"<(.*): (.*)>" | |
let res = matches(for: regexPattern, in: inputString) | |
if res.count != 3 { | |
return nil | |
} | |
let alloc = (res[0] == "dealloc") ? AllocType.dealloc : AllocType.alloc | |
let className = res[1] | |
let pointer = res[2] | |
return LigneResult(className: className, pointer: pointer, type: alloc) | |
} | |
static func filterByPointer(lignes : [LigneResult]) -> [String:[LigneResult]] { | |
var pointerOriented : [String:[LigneResult]] = [:] | |
for aLigne in lignes { | |
if let _ = pointerOriented[aLigne.pointer] { | |
pointerOriented[aLigne.pointer]?.append(aLigne) | |
} else { | |
pointerOriented[aLigne.pointer] = [aLigne] | |
} | |
} | |
return pointerOriented | |
} | |
static func filterByClassName(lignes : [LigneResult]) -> [String:[String : [LigneResult]]] { | |
var pointerOriented : [String:[LigneResult]] = [:] | |
for aLigne in lignes { | |
if let _ = pointerOriented[aLigne.className] { | |
pointerOriented[aLigne.className]?.append(aLigne) | |
} else { | |
pointerOriented[aLigne.className] = [aLigne] | |
} | |
} | |
var res : [String:[String : [LigneResult]]] = [:] | |
for (className, lignes) in pointerOriented { | |
res[className] = filterByPointer(lignes :lignes) | |
} | |
return res | |
} | |
static func transformLigneDataToResult(lignes : [LigneResult]) -> [AllocationResult] { | |
var output : [AllocationResult] = [] | |
let filteredLignes = filterByClassName(lignes: lignes) | |
for (className, pointerLigne) in filteredLignes { | |
var allocR = AllocationResult(className: className) | |
allocR.pointerNumber = pointerLigne.count | |
var numberOfValidDealloc = 0 | |
var numberOfMissDealloc = 0 | |
for (_, lignes) in pointerLigne { | |
let allocs = lignes.reduce(0, { (res, l) in | |
if (l.type == .alloc) { | |
return res + 1 | |
} | |
return res + 0 | |
}) | |
let deallocs = lignes.reduce(0, { (res, l) in | |
if (l.type == .dealloc) { | |
return res + 1 | |
} | |
return res + 0 | |
}) | |
if allocs - deallocs == 0 { | |
numberOfValidDealloc = numberOfValidDealloc + 1 | |
} else { | |
numberOfMissDealloc = numberOfMissDealloc + 1 | |
} | |
} | |
allocR.numberOfValidDealloc = numberOfValidDealloc | |
allocR.numberOfMissDealloc = numberOfMissDealloc | |
output.append(allocR) | |
} | |
return output | |
} | |
public static func generateAllocationResult(inputTexte : String) -> [AllocationResult] { | |
let lines = inputTexte.components(separatedBy: .newlines) | |
let results = lines.compactMap(getLigneData) | |
let allocationsStats = transformLigneDataToResult(lignes : results) | |
return allocationsStats | |
} | |
} | |
let inputAllocation = """ | |
-- alloc 1 -- @"<PagesJaunes.TabBarViewer: 0x7fc789803600>" 0x0 | |
-- alloc 2 -- @"<UINavigationController: 0x7fc788001a00>" 0x0 | |
-- alloc 3 -- @"<UINavigationController: 0x7fc7880aa800>" 0x0 | |
-- alloc 4 -- @"<UINavigationController: 0x7fc789822a00>" 0x0 | |
-- alloc 5 -- @"<PagesJaunes.HomeViewer: 0x7fc787d0ae40>" 0x0 | |
-- alloc 6 -- @"<PagesJaunes.HPShortcutViewer: 0x7fc78a11eab0>" 0x0 | |
-- alloc 7 -- @"<PagesJaunes.HPInterruptedActionsViewer: 0x7fc787e13d50>" 0x0 | |
-- alloc 8 -- @"<PagesJaunes.HPEngagementViewer: 0x7fc787e13690>" 0x0 | |
-- alloc 9 -- @"<APMBadgeViewController: 0x7fc787c1ba20>" 0x0 | |
-- alloc 10 -- @"<PagesJaunes.HistoricViewer: 0x7fc787d11150>" 0x0 | |
-- alloc 11 -- @"<APMBadgeViewController: 0x7fc78a1aa8a0>" 0x0 | |
-- alloc 12 -- @"<UIViewController: 0x7fc787e7bcc0>" 0x0 | |
-- alloc 13 -- @"<PagesJaunes.InternalFDViewController: 0x7fc78c07e000>" 0x0 | |
-- alloc 14 -- @"<PagesJaunes.FDModulesViewController: 0x7fc787c55d40>" 0x0 | |
-- alloc 15 -- @"<UIViewController: 0x7fc787c60640>" 0x0 | |
-- alloc 16 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787d75620>" 0x0 | |
-- alloc 17 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc78a1da260>" 0x0 | |
-- alloc 18 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787c75800>" 0x0 | |
-- alloc 19 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787c78c10>" 0x0 | |
-- alloc 20 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc78a1dd1e0>" 0x0 | |
-- alloc 21 -- @"<PagesJaunes.SimpleModuleViewControllerStickerTop: 0x7fc787d71320>" 0x0 | |
-- alloc 22 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc78a1e0710>" 0x0 | |
-- alloc 23 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787f1b940>" 0x0 | |
-- alloc 24 -- @"<PagesJaunes.SimpleModuleViewControllerStickerTop: 0x7fc787e99b00>" 0x0 | |
-- alloc 25 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787e9d210>" 0x0 | |
-- alloc 26 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787c714e0>" 0x0 | |
-- alloc 27 -- @"<APMBadgeViewController: 0x7fc787c39970>" 0x0 | |
-- alloc 28 -- @"<UIViewController: 0x7fc78a2183a0>" 0x0 | |
-- alloc 29 -- @"<APMBadgeViewController: 0x7fc787c6bba0>" 0x0 | |
-- alloc 30 -- @"<UIViewController: 0x7fc787d564e0>" 0x0 | |
-- dealloc @"<APMBadgeViewController: 0x7fc787c1ba20>" 0x0 | |
-- dealloc @"<APMBadgeViewController: 0x7fc78a1aa8a0>" 0x0 | |
-- dealloc @"<UIViewController: 0x7fc787e7bcc0>" 0x0 | |
-- dealloc @"<APMBadgeViewController: 0x7fc787c39970>" 0x0 | |
-- dealloc @"<UIViewController: 0x7fc78a2183a0>" 0x0 | |
-- dealloc @"<PagesJaunes.InternalFDViewController: 0x7fc78c07e000>" 0x0 | |
-- dealloc @"<APMBadgeViewController: 0x7fc787c6bba0>" 0x0 | |
-- dealloc @"<UIViewController: 0x7fc787d564e0>" 0x0 | |
""" | |
let res = AllocDeallocTester.generateAllocationResult(inputTexte: inputAllocation) | |
print(res) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment