github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/compiler/filter/assign.go (about) 1 package filter 2 3 import ( 4 "go/ast" 5 "go/token" 6 "go/types" 7 8 "github.com/goplusjs/gopherjs/compiler/astutil" 9 ) 10 11 func Assign(stmt ast.Stmt, info *types.Info, pkg *types.Package) ast.Stmt { 12 if s, ok := stmt.(*ast.AssignStmt); ok && s.Tok != token.ASSIGN && s.Tok != token.DEFINE { 13 var op token.Token 14 switch s.Tok { 15 case token.ADD_ASSIGN: 16 op = token.ADD 17 case token.SUB_ASSIGN: 18 op = token.SUB 19 case token.MUL_ASSIGN: 20 op = token.MUL 21 case token.QUO_ASSIGN: 22 op = token.QUO 23 case token.REM_ASSIGN: 24 op = token.REM 25 case token.AND_ASSIGN: 26 op = token.AND 27 case token.OR_ASSIGN: 28 op = token.OR 29 case token.XOR_ASSIGN: 30 op = token.XOR 31 case token.SHL_ASSIGN: 32 op = token.SHL 33 case token.SHR_ASSIGN: 34 op = token.SHR 35 case token.AND_NOT_ASSIGN: 36 op = token.AND_NOT 37 default: 38 panic(s.Tok) 39 } 40 41 var list []ast.Stmt 42 43 var viaTmpVars func(expr ast.Expr, name string) ast.Expr 44 viaTmpVars = func(expr ast.Expr, name string) ast.Expr { 45 switch e := astutil.RemoveParens(expr).(type) { 46 case *ast.IndexExpr: 47 return astutil.SetType(info, info.TypeOf(e), &ast.IndexExpr{ 48 X: viaTmpVars(e.X, "_slice"), 49 Index: viaTmpVars(e.Index, "_index"), 50 }) 51 52 case *ast.SelectorExpr: 53 sel, ok := info.Selections[e] 54 if !ok { 55 // qualified identifier 56 return e 57 } 58 newSel := &ast.SelectorExpr{ 59 X: viaTmpVars(e.X, "_struct"), 60 Sel: e.Sel, 61 } 62 info.Selections[newSel] = sel 63 return astutil.SetType(info, info.TypeOf(e), newSel) 64 65 case *ast.StarExpr: 66 return astutil.SetType(info, info.TypeOf(e), &ast.StarExpr{ 67 X: viaTmpVars(e.X, "_ptr"), 68 }) 69 70 case *ast.Ident, *ast.BasicLit: 71 return e 72 73 default: 74 tmpVar := astutil.NewIdent(name, info.TypeOf(e), info, pkg) 75 list = append(list, &ast.AssignStmt{ 76 Lhs: []ast.Expr{tmpVar}, 77 Tok: token.DEFINE, 78 Rhs: []ast.Expr{e}, 79 }) 80 return tmpVar 81 82 } 83 } 84 85 lhs := viaTmpVars(s.Lhs[0], "_val") 86 87 list = append(list, &ast.AssignStmt{ 88 Lhs: []ast.Expr{lhs}, 89 Tok: token.ASSIGN, 90 Rhs: []ast.Expr{ 91 astutil.SetType(info, info.TypeOf(s.Lhs[0]), &ast.BinaryExpr{ 92 X: lhs, 93 Op: op, 94 Y: astutil.SetType(info, info.TypeOf(s.Rhs[0]), &ast.ParenExpr{ 95 X: s.Rhs[0], 96 }), 97 }), 98 }, 99 }) 100 101 return &ast.BlockStmt{ 102 List: list, 103 } 104 } 105 return stmt 106 }