今天我們要透過,對變數下 cursorInfo
取得他的原始來源。
self
針對三種不同情況查詢 self 所在位置。
extension ReferenceTests {
final func testSelf() throws {
let code = """
class A {
var a: A {
return self
}
func b() -> A {
return self
}
lazy var c: A = {
return self
}()
init() {}
}
"""
try prepare(code: code) { client in
/// a
try XCTAssertEqual(client(40).offset, 23)
XCTAssertEqual(code[40...43], "self")
XCTAssertEqual(code[23], "{")
/// b
try XCTAssertEqual(client(87).offset, 61)
XCTAssertEqual(code[87...90], "self")
XCTAssertEqual(code[61...68], "b() -> A")
/// c
try XCTAssertEqual(client(136).offset, 112)
XCTAssertEqual(code[136...139], "self")
XCTAssertEqual(code[112...115], "c: A")
}
}
}
從第一個 computed var a
可以蒐集到一些有用的資訊。
offset 23
A
// var a: A {
// return self
// }
po client(40)
- key : "key.offset"
- value : 23
- key : "key.kind"
- value : "source.lang.swift.ref.var.local"
- key : "key.typename"
- value : "A"
應此我們可以知道 self
的來源位置
extension ReferenceTests {
final func testCapture() throws {
let code = """
class A {
func example() {
let a = A()
let b: () -> () = { [aa = a, a, weak self, this = self] in
print(aa, a, self, this)
}
}
init() {}
}
"""
/// reference of capture list
try prepare(code: code) { client in
/// aa = a, `a`
try XCTAssertEqual(client(86).offset, 44)
XCTAssertEqual(code[86], "a")
XCTAssertEqual(code[44], "a")
/// a, `a`
try XCTAssertEqual(client(89).offset, 89)
XCTAssertEqual(code[89], "a")
}
/// reference to capture list
try prepare(code: code) { client in
/// aa
try XCTAssertEqual(client(137).offset, 81)
/// a
try XCTAssertEqual(client(141).offset, 89)
/// self
try XCTAssertEqual(client(144).offset, 97)
/// this
try XCTAssertEqual(client(150).offset, 103)
}
}
從這個例子可以看到
let a = A()
let b: () -> () = { [aa = a/*1*/, a/*2*/] in
print(aa, a)
}
L3.aa 指向 L2.aa
L2.a1 指向 L1.a
是符合預期的。
但是 L2.a2 是指向 L2.a2
也就是說我們無法透過 cursorInfo 查詢到 L2.a2 的原始來源
除非,我們將 [a2]
改寫成 [a = a]
([a2 = a3]
)