Skip to content

Commit

Permalink
Merge pull request #4 from keith/swift-4.0
Browse files Browse the repository at this point in the history
Update to Swift 4.x
  • Loading branch information
keith committed May 14, 2018
2 parents df86eea + 0198550 commit 92d8edd
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: objective-c
osx_image: xcode7.3
osx_image: xcode9.3
script:
- make test
24 changes: 12 additions & 12 deletions Demangler/Demangler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public enum DemangleResult {

public final class Demangler {
private let ExtractFromObjCRegex = try! NSRegularExpression(pattern: "^[-+]\\[([^\\]]+)\\s+[^\\]]+\\]$",
options: [.AnchorsMatchLines])
options: [.anchorsMatchLines])

private var internalDemangler: InternalDemangler = LibraryDemangler()

Expand Down Expand Up @@ -52,29 +52,29 @@ public final class Demangler {
- returns: The demangled name integrated into the ObjC selector
*/
func integrateDemangledString(intoSelector selector: String, string: String) -> String {
let range = NSRange(location: 0, length: selector.characters.count)
let matches = self.ExtractFromObjCRegex.matchesInString(selector, options: [], range: range)
let range = NSRange(location: 0, length: selector.utf16.count)
let matches = self.ExtractFromObjCRegex.matches(in: selector, options: [], range: range)
assert(matches.count <= 1)
assert(matches.first?.numberOfRanges == 2)

let match = matches.first!
let matchRange = match.rangeAtIndex(1)
let matchRange = match.range(at: 1)
let selectorString = selector as NSString
let start = selectorString.substringWithRange(NSRange(location: 0, length: matchRange.location))
let start = selectorString.substring(with: NSRange(location: 0, length: matchRange.location))
let position = matchRange.location + matchRange.length
let end = selectorString.substringWithRange(NSRange(location: position,
let end = selectorString.substring(with: NSRange(location: position,
length: selectorString.length - position))
return "\(start)\(string)\(end)"
}

func extractMangledString(fromObjCSelector selector: String) -> (String, Bool) {
let range = NSRange(location: 0, length: selector.characters.count)
let matches = self.ExtractFromObjCRegex.matchesInString(selector, options: [], range: range)
let range = NSRange(location: 0, length: selector.utf16.count)
let matches = self.ExtractFromObjCRegex.matches(in: selector, options: [], range: range)
assert(matches.count <= 1)

if let match = matches.first where match.numberOfRanges == 2 {
let range = match.rangeAtIndex(1)
return ((selector as NSString).substringWithRange(range), true)
if let match = matches.first, match.numberOfRanges == 2 {
let range = match.range(at: 1)
return ((selector as NSString).substring(with: range), true)
}

return (selector, false)
Expand All @@ -90,7 +90,7 @@ public final class Demangler {
- returns: true if a demangle should be attempted
*/
func shouldDemangle(string string: String) -> Bool {
func shouldDemangle(string: String) -> Bool {
if string.hasPrefix("__T") {
return true
}
Expand Down
12 changes: 6 additions & 6 deletions Demangler/LibraryDemangler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,29 @@ private let kDemangleLibraryPath = ("/Applications/Xcode.app/Contents/Developer/
private let kBufferSize = 1024

final class LibraryDemangler: InternalDemangler {
private var handle: UnsafeMutablePointer<Void> = {
private var handle: UnsafeMutableRawPointer = {
return dlopen(kDemangleLibraryPath, RTLD_NOW)
}()

private lazy var internalDemangleFunction: SwiftDemangleFunction = {
let address = dlsym(self.handle, "swift_demangle_getDemangledName")
return unsafeBitCast(address, SwiftDemangleFunction.self)
return unsafeBitCast(address, to: SwiftDemangleFunction.self)
}()

func demangle(string string: String) -> String? {
func demangle(string: String) -> String? {
let formattedString = self.removingExcessLeadingUnderscores(fromString: string)
let outputString = UnsafeMutablePointer<CChar>.alloc(kBufferSize)
let outputString = UnsafeMutablePointer<CChar>.allocate(capacity: kBufferSize)
let resultSize = self.internalDemangleFunction(formattedString, outputString, kBufferSize)
if resultSize > kBufferSize {
NSLog("Attempted to demangle string with length \(resultSize) but buffer size \(kBufferSize)")
}

return String(CString: outputString, encoding: NSUTF8StringEncoding)
return String(cString: outputString, encoding: .utf8)
}

private func removingExcessLeadingUnderscores(fromString string: String) -> String {
if string.hasPrefix("__T") {
return String(string.characters.dropFirst())
return String(string.dropFirst())
}

return string
Expand Down
8 changes: 4 additions & 4 deletions Demangler/ShellDemangler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ final class ShellDemangler: InternalDemangler {
return self.output(forShellCommand: "/usr/bin/xcrun --find swift-demangle")!
}()

func demangle(string string: String) -> String? {
func demangle(string: String) -> String? {
return self.output(forShellCommand: self.demangleCommand(forString: string))
}

Expand All @@ -16,8 +16,8 @@ final class ShellDemangler: InternalDemangler {
private func output(forShellCommand command: String) -> String? {
assert(command.split().count >= 2)

let task = NSTask()
let pipe = NSPipe()
let task = Process()
let pipe = Pipe()
let components = command.split()

task.launchPath = components.first
Expand All @@ -28,6 +28,6 @@ final class ShellDemangler: InternalDemangler {
task.waitUntilExit()

let data = pipe.fileHandleForReading.readDataToEndOfFile()
return String(data: data, encoding: NSUTF8StringEncoding)?.strip()
return String(data: data, encoding: .utf8)?.strip()
}
}
4 changes: 2 additions & 2 deletions Demangler/String+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import Foundation

extension String {
func split() -> [String] {
return self.characters.split(" ").map(String.init)
return self.split(separator: " ").map(String.init)
}

func strip() -> String {
return self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
}

2 changes: 1 addition & 1 deletion DemanglerTests/DemanglerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ final class DemanglerTests: XCTestCase {

func testDemangleSanity() {
let demangledResult = demangler.demangle(string: "__TFV3foo3BarCfT_S0_")
let expectedName = "foo.Bar.init () -> foo.Bar"
let expectedName = "foo.Bar.init() -> foo.Bar"

XCTAssertEqual(demangledResult, DemangleResult.Success(expectedName))
}
Expand Down
2 changes: 2 additions & 0 deletions Swift Demangle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
Expand Down Expand Up @@ -490,6 +491,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_VERSION = 4.0;
};
name = Release;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
12 changes: 6 additions & 6 deletions Swift Demangle/HPDocument+Extension.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extension HPDocument {
func wait(withReason reason: String, forWork work: (document: HPDocument, file: HPDisassembledFile,
shouldCancel: UnsafeMutablePointer<Bool>) -> Void)
func wait(withReason reason: String,
forWork work: @escaping (HPDocument, HPDisassembledFile, UnsafeMutablePointer<Bool>) -> Void)
{
if self.isWaiting() {
return self.logErrorStringMessage("Already waiting on something")
Expand All @@ -11,7 +11,7 @@ extension HPDocument {
}

var shouldCancel = false
self.beginToWait(reason)
self.begin(toWait: reason)

//
// For some reason passing a cancelBlock crashes 100%. But not if you do it via cycript :/
Expand All @@ -23,10 +23,10 @@ extension HPDocument {
// })
//

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) {
work(document: self, file: file, shouldCancel: &shouldCancel)
DispatchQueue.global(qos: .userInitiated).async {
work(self, file, &shouldCancel)

dispatch_async(dispatch_get_main_queue()) {
DispatchQueue.main.async {
self.updateStaticNames()
self.endWaiting()
}
Expand Down
2 changes: 1 addition & 1 deletion Swift Demangle/NSBundle+Extension.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

extension NSBundle {
extension Bundle {
var pluginVersion: String {
return self.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown"
}
Expand Down
12 changes: 6 additions & 6 deletions Swift Demangle/SwiftDemangle+Actions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ private enum Action {
extension SwiftDemangle {
@objc
func demangleClosestName() {
self.performAction(.DemangleClosest)
self.performAction(action: .DemangleClosest)
}

@objc
func demangleAllProcedures() {
self.performAction(.DemangleAll)
self.performAction(action: .DemangleAll)
}

private func performAction(action: Action) {
let function: HPDocument -> Void
let function: (HPDocument) -> Void
switch action {
case .DemangleClosest:
function = self.demangleClosestName
Expand All @@ -37,8 +37,8 @@ extension SwiftDemangle {

private func demangleClosestName(withDocument document: HPDocument) {
document.wait(withReason: "Demangling Closest Name") { document, file, _ in
let address = file.nearestNamedAddressBeforeVirtualAddress(document.currentAddress())
let mangledString = file.nameForVirtualAddress(address)
let address = file.nearestNamedAddress(beforeVirtualAddress: document.currentAddress())
let mangledString = file.name(forVirtualAddress: address)
let demangleResult = self.demangler.demangle(string: mangledString)
self.handle(demangleResult: demangleResult, forAddress: address, mangledString: mangledString,
file: file, document: document)
Expand All @@ -55,7 +55,7 @@ extension SwiftDemangle {
case .Ignored(let ignoredString):
document.logStringMessage("Ignoring '\(ignoredString)'")
case .Failed(let failedString):
document.logStringMessage("Failed to demangle '\(failedString)'")
document.logStringMessage("Failed to demangle '\(failedString ?? "")'")
}
}
}
10 changes: 5 additions & 5 deletions Swift Demangle/SwiftDemangle+DemangleAll.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ extension SwiftDemangle {
file: HPDisassembledFile,
shouldCancel: UnsafeMutablePointer<Bool>)
{
let segments = file.segments()
let segments = file.segments() ?? []
var procedureCount: Int?

dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
DispatchQueue.global(qos: .default).async {
let totalProcedureCount = segments.reduce(0) { accumulator, segment in
return accumulator + segment.procedures().count
}
Expand All @@ -30,7 +30,7 @@ extension SwiftDemangle {
var processedCount = 0
for segment in segments {
for procedure in segment.procedures() {
if shouldCancel.memory {
if shouldCancel.pointee {
let countString = procedureCount.map(String.init) ?? "Unknown"
return document.logErrorStringMessage(
"Cancelling after demangling \(processedCount) of \(countString) procedures")
Expand All @@ -45,7 +45,7 @@ extension SwiftDemangle {
}

let procedureAddress = procedure.entryPoint()
let mangledString: String? = segment.nameForVirtualAddress(procedureAddress)
let mangledString: String? = segment.name(forVirtualAddress: procedureAddress)
let demangleResult = self.demangler.demangle(string: mangledString)
self.handle(demangleResult: demangleResult, forAddress: procedureAddress,
mangledString: mangledString, file: file, document: document)
Expand All @@ -64,7 +64,7 @@ extension SwiftDemangle {
*/
private func showAnalysisAlertAndCancel(forDocument document: HPDocument) -> Bool {
if document.disassembledFile()?.analysisInProgress() == true {
let response = document.displayAlertWithMessageText("File is still being analyzed",
let response = document.displayAlert(withMessageText: "File is still being analyzed",
defaultButton: "Cancel", alternateButton: "Continue", otherButton: nil,
informativeText: "Would you like to demangle what has already been loaded?")

Expand Down
6 changes: 3 additions & 3 deletions Swift Demangle/SwiftDemangle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ final class SwiftDemangle: NSObject, HopperTool {
}

func pluginUUID() -> HopperUUID {
return self.services.UUIDWithString("C8FAB152-90FC-4C70-9FA2-4828A2DF322F")
return self.services.uuid(with: "C8FAB152-90FC-4C70-9FA2-4828A2DF322F")
}

func pluginName() -> String {
Expand All @@ -23,7 +23,7 @@ final class SwiftDemangle: NSObject, HopperTool {
}

func pluginVersion() -> String {
return NSBundle.mainBundle().pluginVersion
return Bundle.main.pluginVersion
}

func pluginCopyright() -> String {
Expand All @@ -38,7 +38,7 @@ final class SwiftDemangle: NSObject, HopperTool {
return .Plugin_Tool
}

func toolMenuDescription() -> [[String: AnyObject]] {
func toolMenuDescription() -> [[String: Any]] {
return [
[
"Title": "Demangle Swift",
Expand Down

0 comments on commit 92d8edd

Please sign in to comment.