我們一樣還是透過 CursorInfo 查詢
並取得 key.annotated_decl
let a = 1
weak var wa = a
print(wa)
key.annotated_decl
是一個 xml 的格式,但是我們只需要裡面的值
<Declaration>
let a: <Type usr=\"s:Si\">Int</Type>
</Declaration>
<decl.var.local>
<syntaxtype.keyword>weak</syntaxtype.keyword>
<syntaxtype.keyword>var</syntaxtype.keyword>
` `
<decl.name>wa</decl.name>
`: `
<decl.var.type>
<ref.struct usr=\"s:Si\">Int</ref.struct>
?
</decl.var.type>
</decl.var.local>
let a: Int
weak var wa: Int?
最終我們可以取得類似於這三種範例
weak var c: Int?
unowned var c: Int
var c: Int
WeakDetector
為了避免判斷錯誤,於是用一個 visitor 去訪問他
public enum WeakDetector {
public static func detect(code: String) -> Bool {
let target: String = code
let source: SourceFileSyntax = Parser.parse(source: target)
let visitor = WeakVisitor(viewMode: .sourceAccurate)
visitor.walk(source)
return visitor.isHaveWeak || visitor.isHaveUnowned
}
}
private final class WeakVisitor: SyntaxVisitor {
var isHaveWeak: Bool = false
var isHaveUnowned: Bool = false
override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {
let modifiers = node.modifiers?.map { $0.withoutTrivia().description } ?? []
isHaveWeak = modifiers.contains("weak")
isHaveUnowned = modifiers.contains("unowned")
return .skipChildren
}
}