Skip to content

Commit

Permalink
refactor(checkup): Split parsing go syntax tree into separate methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Aerex committed Oct 11, 2022
1 parent 39caa5b commit 244b9c6
Showing 1 changed file with 93 additions and 68 deletions.
161 changes: 93 additions & 68 deletions cmds/checkup.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,89 @@ func getGoFiles(dir string) (files []string) {
return
}

func (cu *Checkup) inspectAssignStmt(stmtMap map[string][]ast.AssignStmt, node *ast.AssignStmt) {
// use a hashmap for defined variables to a list of reassigned variables sharing the same var name
if assignStmt, okIdent := node.Lhs[0].(*ast.Ident); okIdent {
varName := assignStmt.Name
if node.Tok == token.DEFINE {
stmtMap[varName] = []ast.AssignStmt{}
} else if node.Tok == token.ASSIGN {
if _, exists := stmtMap[varName]; exists {
stmtMap[varName] = append(stmtMap[varName], *node)
}
}
}
}

func (cu *Checkup) inspectStmt(translatedStrings []string, stmtMap map[string][]ast.AssignStmt, node ast.AssignStmt) []string {
if strStmtArg, ok := node.Rhs[0].(*ast.BasicLit); ok {
varName := node.Lhs[0].(*ast.Ident).Name
translatedString, err := strconv.Unquote(strStmtArg.Value)
if err != nil {
panic(err.Error())
}
translatedStrings = append(translatedStrings, translatedString)
// apply all translation ids from reassigned variables
if _, exists := stmtMap[varName]; exists {
for _, assignStmt := range stmtMap[varName] {
strVarVal := assignStmt.Rhs[0].(*ast.BasicLit).Value
translatedString, err := strconv.Unquote(strVarVal)
if err != nil {
panic(err.Error())
}
translatedStrings = append(translatedStrings, translatedString)

}
}
}

return translatedStrings
}

func (cu *Checkup) inspectTFunc(translatedStrings []string, stmtMap map[string][]ast.AssignStmt, node ast.CallExpr) []string {
if stringArg, ok := node.Args[0].(*ast.BasicLit); ok {
translatedString, err := strconv.Unquote(stringArg.Value)
if err != nil {
panic(err.Error())
}
translatedStrings = append(translatedStrings, translatedString)
}
if idt, okIdt := node.Args[0].(*ast.Ident); okIdt {
if obj := idt.Obj; obj != nil {
if stmtArg, okStmt := obj.Decl.(*ast.AssignStmt); okStmt {
translatedStrings = cu.inspectStmt(translatedStrings, stmtMap, *stmtArg)
}
}
}

return translatedStrings
}

func (cu *Checkup) inspectCallExpr(translatedStrings []string, stmtMap map[string][]ast.AssignStmt, node *ast.CallExpr) []string {
switch node.Fun.(type) {
case *ast.Ident:
funName := node.Fun.(*ast.Ident).Name
// inspect any T() or t() method calls
if funName == "T" || funName == "t" {
translatedStrings = cu.inspectTFunc(translatedStrings, stmtMap, *node)
}

case *ast.SelectorExpr:
expr := node.Fun.(*ast.SelectorExpr)
if ident, ok := expr.X.(*ast.Ident); ok {
funName := expr.Sel.Name
// inspect any <MODULE>.T() or <MODULE>.t() method calls (eg. i18n.T())
if ident.Name == cu.options.QualifierFlag && (funName == "T" || funName == "t") {
translatedStrings = cu.inspectTFunc(translatedStrings, stmtMap, *node)
}
}
default:
//Skip!
}

return translatedStrings
}

func (cu *Checkup) inspectFile(file string) (translatedStrings []string, err error) {
defineAssignStmtMap := make(map[string][]ast.AssignStmt)
fset := token.NewFileSet()
Expand All @@ -129,75 +212,17 @@ func (cu *Checkup) inspectFile(file string) (translatedStrings []string, err err
ast.Inspect(astFile, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.AssignStmt:
// use a hashmap for defined variables to a list of reassigned variables sharing the same var name
if assignStmt, okIdent := x.Lhs[0].(*ast.Ident); okIdent {
varName := assignStmt.Name
if x.Tok == token.DEFINE {
defineAssignStmtMap[varName] = []ast.AssignStmt{}
} else if x.Tok == token.ASSIGN {
if _, exists := defineAssignStmtMap[varName]; exists {
defineAssignStmtMap[varName] = append(defineAssignStmtMap[varName], *x)
}
}
}
// inspect any potential translation string in defined / assigned statement nodes
// add node to map if variable contains a translation string
// eg: translation := "Hello {{.FirstName}}"
// T(translation)
// translation = "Hello {{.LastName}}"
// T(translation)
cu.inspectAssignStmt(defineAssignStmtMap, x)
case *ast.CallExpr:
switch x.Fun.(type) {
case *ast.Ident:
funName := x.Fun.(*ast.Ident).Name

if funName == "T" || funName == "t" {
if stringArg, okStr := x.Args[0].(*ast.BasicLit); okStr {
translatedString, err := strconv.Unquote(stringArg.Value)
if err != nil {
panic(err.Error())
}
translatedStrings = append(translatedStrings, translatedString)
}
if idt, okIdt := x.Args[0].(*ast.Ident); okIdt {
if obj := idt.Obj; obj != nil {
if stmtArg, okStmt := obj.Decl.(*ast.AssignStmt); okStmt {
if strStmtArg, okStrStmt := stmtArg.Rhs[0].(*ast.BasicLit); okStrStmt {
varName := stmtArg.Lhs[0].(*ast.Ident).Name
translatedString, err := strconv.Unquote(strStmtArg.Value)
if err != nil {
panic(err.Error())
}
translatedStrings = append(translatedStrings, translatedString)
// apply all translation ids from reassigned variables
if _, exists := defineAssignStmtMap[varName]; exists {
for _, assignStmt := range defineAssignStmtMap[varName] {
strVarVal := assignStmt.Rhs[0].(*ast.BasicLit).Value
translatedString, err := strconv.Unquote(strVarVal)
if err != nil {
panic(err.Error())
}
translatedStrings = append(translatedStrings, translatedString)

}
}
}
}
}
}

}
case *ast.SelectorExpr:
expr := x.Fun.(*ast.SelectorExpr)
if ident, ok := expr.X.(*ast.Ident); ok {
funName := expr.Sel.Name
if ident.Name == cu.options.QualifierFlag && (funName == "T" || funName == "t") {
if stringArg, ok := x.Args[0].(*ast.BasicLit); ok {
translatedString, err := strconv.Unquote(stringArg.Value)
if err != nil {
panic(err.Error())
}
translatedStrings = append(translatedStrings, translatedString)
}
}
}
default:
//Skip!
}
// inspect any T()/t() or <MODULE>.T()/<MODULE>.t() (eg. i18n.T()) method calls using map
/// then retrieve a list of translation strings that were passed into method
translatedStrings = cu.inspectCallExpr(translatedStrings, defineAssignStmtMap, x)
}
return true
})
Expand Down

0 comments on commit 244b9c6

Please sign in to comment.