Перейти статический анализ: найти переменные уровня пакета, доступные только для чтения
Используя статический анализ, должно быть возможно определить, какие переменные уровня пакета всегда доступны только для чтения... то есть значение после инициализации никогда не изменяется программой.
Моя проблема с радостью будет терпеть ложные негативы - например, мне нужно знать только переменные, которые доступны только для чтения. Если анализ не уверен в отношении некоторых переменных, они могут быть включены в набор для чтения и записи.
Например, в следующей программе c, f, i и l никогда не изменяются:
package main
var a = 1
var b = 1
var c = 1 // never modified
var d = []int{1, 2}
var e = []int{1, 2}
var f = []int{1, 2} // never modified
var g = map[string]int{"a": 1}
var h = map[string]int{"a": 1}
var i = map[string]int{"a": 1} // never modified
var j = T{a: 1}
var k = T{a: 1}
var l = T{a: 1} // never modified
func main() {
a = 2 // modifies a
modInt(&b) // modifies b
useInt(c) // uses c but doesn't modify
d[0] = 2 // modifies d
modSlice(e) // modifies e
useInt(f[0]) // uses f but doesn't modify
g["a"] = 2 // modifies g
modMap(h) // modifies h
useInt(i["a"]) // uses i but doesn't modify
j.a = 2 // modifies j
modT(&k) // modifies k
useInt(l.a) // uses i but doesn't modify
}
func modInt(in *int) {
*in = 2
}
func modSlice(in []int) {
in[0] = 2
}
func modMap(in map[string]int) {
in["a"] = 2
}
func modT(in *T) {
in.a = 2
}
func useInt(i int) {
println(i)
}
type T struct {
a int
}
Я знаком с пакетами go/ast, и у меня есть практические знания о go/types, но пакеты анализа ssa и указателя немного выходят за рамки моих знаний. Кажется, есть много концепций, которые нужно переварить, и я немного ошеломлен.
Два вопроса:
- Есть ли пакет, который сделает это для меня?
- Если нет, есть ли у вас какие-либо советы о том, какие концепции анализа SSA / указателя помогут в этом?