Search code examples
swiftlineswift5directive

How to get the current line in swift 5.0


I want to convert a codable struct into keyvalue pairs so that I can write it to a row in a csv so I can present it in excel, or apple numbers. I will need some of the cells in the csv to be reference based calculations.

So, for example, suppose I have A1 as revenue and A2 as an expense and I want A3 to be the net income or "=A1-A2"

struct FinanceSummary {
  var expense: Decimal
  var revenue: Decimal

  var lineReference: Int { #line + 2 } // + 2 for the 2 lines below before key pairs
  func keyPairs(row: Int) -> KeyValuePairs<String, String> {
    [
      "expense": "\(expense)",
      "revenue": "\(revenue)",
      "income": "=A\(#line - lineReference - 1) - A\(#line - lineReference - 2)"
    ]
  }
}

However, where I used to be able to use #line to get the line number, when I try that I get an error: #line directive was renamed to #sourceLocation, and when I use #sourceLocation, I get another error: Expected '(' in #sourceLocation directive because the compiler expects me to initialize the source location with a file and line number. However, I don't want to tell the compiler, what file and line I am on. I want the compiler to tell me.


Solution

  • The error message is misleading. Apparently, the #line directive can not be the first expression in the body of the computed property (and I do not know why). As a workaround you can write

    var lineReference: Int { return #line + 2 }
    

    or

    var lineReference: Int { 2 + #line }
    

    or simply use a stored property instead:

    let lineReference = #line + 2