const pvagenfile … var pvaDoGenerate … func TestMain(m *testing.M) { … } // TestPutVarAbbrevGenerator checks that putvarabbrevgen.go is kept in sync // with the contents of functions putvar and putAbstractVar. If test flag -generate // is specified the file is regenerated instead. // // The block of code in putvar and putAbstractVar that picks the correct // abbrev is also generated automatically by this function by looking at all // the possible paths in their CFG and the order in which putattr is called. // // There are some restrictions on how putattr can be used in putvar and // putAbstractVar: // // 1. it shouldn't appear inside a for or switch statements // 2. it can appear within any number of nested if/else statements but the // conditionals must not change after putvarAbbrev/putAbstractVarAbbrev // are called // 3. the form argument of putattr must be a compile time constant // 4. each putattr call must be followed by a comment containing the name of // the attribute it is setting // // TestPutVarAbbrevGenerator will fail if (1) or (4) are not respected and // the generated code will not compile if (3) is violated. Violating (2) // will result in code silently wrong code (which will usually be detected // by one of the tests that parse debug_info). func TestPutVarAbbrevGenerator(t *testing.T) { … } func pvagenerate(t *testing.T) string { … } type pvacfgnode … // pvacfgbody generates a simplified CFG for a slice of statements, // containing only calls to putattr and the if statements affecting them. func pvacfgbody(t *testing.T, fset *token.FileSet, cm ast.CommentMap, body []ast.Stmt) (start, end *pvacfgnode) { … } func pvacfgif(t *testing.T, fset *token.FileSet, cm ast.CommentMap, ifstmt *ast.IfStmt) (start, end *pvacfgnode) { … } func exprToString(t ast.Expr) string { … } // findLineComment finds the line comment for statement stmt. func findLineComment(cm ast.CommentMap, stmt *ast.ExprStmt) *ast.Comment { … } // pvacfgvisit visits the CFG depth first, populates abbrevs with all // possible dwAbbrev definitions and returns a tree of if/else statements // that picks the correct abbrev. func pvacfgvisit(pvacfg *pvacfgnode, abbrevs map[string]int) ast.Stmt { … } func pvacfgvisitnode(pvacfg *pvacfgnode, tag string, path []*pvacfgnode, abbrevs map[string]int) ast.Stmt { … } func toabbrev(tag string, path []*pvacfgnode) string { … }