Skip to content

Commit

Permalink
Merge pull request #106 from birwin93/fix-parsing-logic
Browse files Browse the repository at this point in the history
Fixes logic with swiftc parsing
  • Loading branch information
ecamacho committed Sep 7, 2020
2 parents 188b053 + 748f101 commit 028ddf6
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ class SwiftCompilerFunctionTimeOptionParser: SwiftCompilerTimeOptionParser {

private static let compilerFlag = "-debug-time-function-bodies"

private static let invalidLoc = "<invalid loc>"

private lazy var regexp: NSRegularExpression? = {
let pattern = "[\\t*|\\r]([0-9]+\\.[0-9]+)ms\\t+(<invalid\\tloc>|[^\\t]+)\\t+(.+)\\r"
return NSRegularExpression.fromPattern(pattern)
}()

func hasCompilerFlag(commandDesc: String) -> Bool {
commandDesc.range(of: Self.compilerFlag) != nil
}
Expand All @@ -53,62 +46,35 @@ class SwiftCompilerFunctionTimeOptionParser: SwiftCompilerTimeOptionParser {
}

private func parse(command: String, occurrences: Int) -> [SwiftFunctionTime]? {
guard let regexp = regexp else {
return nil
}
let range = NSRange(location: 0, length: command.count)
let matches = regexp.matches(in: command, options: .reportProgress, range: range)
let functionTimes = matches.compactMap { result -> SwiftFunctionTime? in
let durationString = command.substring(result.range(at: 1))
let file = command.substring(result.range(at: 2))
// some entries are invalid, we discard them
if isInvalid(fileName: file) {
return nil
}
let functions: [SwiftFunctionTime] = command.components(separatedBy: "\r").compactMap { commandLine in

// 0.14ms /users/spotify/project/SomeFile.swift:10:12 someMethod(param:)
let parts = commandLine.components(separatedBy: "\t")

let name = command.substring(result.range(at: 3))
guard let (fileName, location) = parseFunctionLocation(file) else {
guard parts.count == 3 else {
return nil
}
let fileURL = prefixWithFileURL(fileName: fileName)
guard let (line, column) = parseLocation(location) else {

// 0.14ms
let duration = parseCompileDuration(parts[0])

// /users/spotify/project/SomeFile.swift:10:12
let fileAndLocation = parts[1]
guard let (file, line, column) = parseNameAndLocation(from: fileAndLocation) else {
return nil
}

let duration = parseCompileDuration(durationString)
return SwiftFunctionTime(file: fileURL,
durationMS: duration,
startingLine: line,
startingColumn: column,
signature: name,
occurrences: occurrences)
}
return functionTimes
}
// someMethod(param:)
let signature = parts[2]

private func parseFunctionLocation(_ function: String) -> (String, String)? {
guard let colonIndex = function.firstIndex(of: ":") else {
return nil
return SwiftFunctionTime(file: file,
durationMS: duration,
startingLine: line,
startingColumn: column,
signature: signature,
occurrences: occurrences)
}
let functionName = function[..<colonIndex]
let locationIndex = function.index(after: colonIndex)
let location = function[locationIndex...]

return (String(functionName), String(location))
}

private func parseLocation(_ location: String) -> (Int, Int)? {
guard let colonIndex = location.firstIndex(of: ":") else {
return nil
}
let line = location[..<colonIndex]
let columnIndex = location.index(after: colonIndex)
let column = location[columnIndex...]
guard let lineNumber = Int(String(line)),
let columnNumber = Int(String(column)) else {
return nil
}
return (lineNumber, columnNumber)
return functions
}

}
26 changes: 23 additions & 3 deletions Sources/XCLogParser/parser/SwiftCompilerTimeOptionParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,32 @@ protocol SwiftCompilerTimeOptionParser {

extension SwiftCompilerTimeOptionParser {

func isInvalid(fileName: String) -> Bool {
return fileName == "<invalid loc>"
/// Parses /users/spotify/project/SomeFile.swift:10:12
/// - Returns: ("file:///users/spotify/project/SomeFile.swift", 10, 12)
// swiftlint:disable:next large_tuple
func parseNameAndLocation(from fileAndLocation: String) -> (String, Int, Int)? {
// /users/spotify/project/SomeFile.swift:10:12
let fileAndLocationParts = fileAndLocation.components(separatedBy: ":")
let rawFile = fileAndLocationParts[0]

guard rawFile != "<invalid loc>" else {
return nil
}

guard fileAndLocationParts.count == 3 else {
return nil
}

let file = prefixWithFileURL(fileName: rawFile)
let line = Int(fileAndLocationParts[1])!
let column = Int(fileAndLocationParts[2])!

return (file, line, column)
}

/// Parses
func parseCompileDuration(_ durationString: String) -> Double {
if let duration = Double(durationString) {
if let duration = Double(durationString.replacingOccurrences(of: "ms", with: "")) {
return duration
}
return 0.0
Expand Down
44 changes: 17 additions & 27 deletions Sources/XCLogParser/parser/SwiftCompilerTypeCheckOptionParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ class SwiftCompilerTypeCheckOptionParser: SwiftCompilerTimeOptionParser {

private static let compilerFlag = "-debug-time-expression-type-checking"

private static let invalidLoc = "<invalid loc>"

private lazy var regexp: NSRegularExpression? = {
let pattern = "\\t*([0-9]+\\.[0-9]+)ms\\t(.+):([0-9]+):([0-9]+)\\r"
return NSRegularExpression.fromPattern(pattern)
}()

func hasCompilerFlag(commandDesc: String) -> Bool {
commandDesc.range(of: Self.compilerFlag) != nil
}
Expand All @@ -52,32 +45,29 @@ class SwiftCompilerTypeCheckOptionParser: SwiftCompilerTimeOptionParser {
}

private func parse(command: String, occurrences: Int) -> [SwiftTypeCheck]? {
guard let regexp = regexp else {
return nil
}
let range = NSRange(location: 0, length: command.count)
let matches = regexp.matches(in: command, options: .reportProgress, range: range)
let typeCheckerTimes = matches.compactMap { result -> SwiftTypeCheck? in
return command.components(separatedBy: "\r").compactMap { commandLine in
// 0.14ms /users/spotify/project/SomeFile.swift:10:12
let parts = commandLine.components(separatedBy: "\t")

let durationString = command.substring(result.range(at: 1))
let fileName = command.substring(result.range(at: 2))
let lineStr = command.substring(result.range(at: 3))
let columnStr = command.substring(result.range(at: 4))
if isInvalid(fileName: fileName) {
guard parts.count == 2 else {
return nil
}
guard let line = Int(lineStr), let column = Int(columnStr) else {

// 0.14ms
let duration = parseCompileDuration(parts[0])

// /users/spotify/project/SomeFile.swift:10:12
let fileAndLocation = parts[1]
guard let (file, line, column) = parseNameAndLocation(from: fileAndLocation) else {
return nil
}
let fileURL = prefixWithFileURL(fileName: fileName)
let duration = parseCompileDuration(durationString)
return SwiftTypeCheck(file: fileURL,
durationMS: duration,
startingLine: line,
startingColumn: column,
occurrences: occurrences)

return SwiftTypeCheck(file: file,
durationMS: duration,
startingLine: line,
startingColumn: column,
occurrences: occurrences)
}
return typeCheckerTimes
}

}
10 changes: 5 additions & 5 deletions Tests/XCLogParserTests/SwiftCompilerParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class SwiftCompilerParserTests: XCTestCase {
let emptylogSection = getFakeSwiftcSection(text: "text",
commandDescription: "command")
let text =
"\t0.05ms\t/Users/user/\(rawFile).swift:9:9\tgetter textLabel\r" +
"\t4.96ms\t/Users/user/\(rawFile).swift:11:14\tinitializer init(frame:)\r" +
"\t0.04ms\t<invalid loc>\tgetter None\r"
"0.05ms\t/Users/user/\(rawFile).swift:9:9\tgetter textLabel\r" +
"4.96ms\t/Users/user/\(rawFile).swift:11:14\tinitializer init(frame:)\r" +
"0.04ms\t<invalid loc>\tgetter None\r"
let swiftTimesLogSection = getFakeSwiftcSection(text:
text, commandDescription: "-debug-time-function-bodies")

Expand Down Expand Up @@ -82,11 +82,11 @@ class SwiftCompilerParserTests: XCTestCase {
commandDescription: "command")

let swiftTimesLogSection = getFakeSwiftcSection(text:
"\t0.72ms\t/Users/\(rawFile).swift:19:15\r",
"0.72ms\t/Users/\(rawFile).swift:19:15\r",
commandDescription: "-debug-time-expression-type-checking")

let duplicatedSwiftTimeslogSection = getFakeSwiftcSection(text:
"\t0.72ms\t/Users/\(rawFile).swift:19:15\r",
"0.72ms\t/Users/\(rawFile).swift:19:15\r",
commandDescription: "-debug-time-expression-type-checking")
let expectedFile = "file:///Users/\(escapedFile).swift"
parser.addLogSection(emptylogSection)
Expand Down

0 comments on commit 028ddf6

Please sign in to comment.