You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
2.3 KiB
107 lines
2.3 KiB
package filter
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/token"
|
|
"go/types"
|
|
|
|
"github.com/gopherjs/gopherjs/compiler/astutil"
|
|
)
|
|
|
|
func Assign(stmt ast.Stmt, info *types.Info, pkg *types.Package) ast.Stmt {
|
|
if s, ok := stmt.(*ast.AssignStmt); ok && s.Tok != token.ASSIGN && s.Tok != token.DEFINE {
|
|
var op token.Token
|
|
switch s.Tok {
|
|
case token.ADD_ASSIGN:
|
|
op = token.ADD
|
|
case token.SUB_ASSIGN:
|
|
op = token.SUB
|
|
case token.MUL_ASSIGN:
|
|
op = token.MUL
|
|
case token.QUO_ASSIGN:
|
|
op = token.QUO
|
|
case token.REM_ASSIGN:
|
|
op = token.REM
|
|
case token.AND_ASSIGN:
|
|
op = token.AND
|
|
case token.OR_ASSIGN:
|
|
op = token.OR
|
|
case token.XOR_ASSIGN:
|
|
op = token.XOR
|
|
case token.SHL_ASSIGN:
|
|
op = token.SHL
|
|
case token.SHR_ASSIGN:
|
|
op = token.SHR
|
|
case token.AND_NOT_ASSIGN:
|
|
op = token.AND_NOT
|
|
default:
|
|
panic(s.Tok)
|
|
}
|
|
|
|
var list []ast.Stmt
|
|
|
|
var viaTmpVars func(expr ast.Expr, name string) ast.Expr
|
|
viaTmpVars = func(expr ast.Expr, name string) ast.Expr {
|
|
switch e := astutil.RemoveParens(expr).(type) {
|
|
case *ast.IndexExpr:
|
|
return astutil.SetType(info, info.TypeOf(e), &ast.IndexExpr{
|
|
X: viaTmpVars(e.X, "_slice"),
|
|
Index: viaTmpVars(e.Index, "_index"),
|
|
})
|
|
|
|
case *ast.SelectorExpr:
|
|
sel, ok := info.Selections[e]
|
|
if !ok {
|
|
// qualified identifier
|
|
return e
|
|
}
|
|
newSel := &ast.SelectorExpr{
|
|
X: viaTmpVars(e.X, "_struct"),
|
|
Sel: e.Sel,
|
|
}
|
|
info.Selections[newSel] = sel
|
|
return astutil.SetType(info, info.TypeOf(e), newSel)
|
|
|
|
case *ast.StarExpr:
|
|
return astutil.SetType(info, info.TypeOf(e), &ast.StarExpr{
|
|
X: viaTmpVars(e.X, "_ptr"),
|
|
})
|
|
|
|
case *ast.Ident, *ast.BasicLit:
|
|
return e
|
|
|
|
default:
|
|
tmpVar := astutil.NewIdent(name, info.TypeOf(e), info, pkg)
|
|
list = append(list, &ast.AssignStmt{
|
|
Lhs: []ast.Expr{tmpVar},
|
|
Tok: token.DEFINE,
|
|
Rhs: []ast.Expr{e},
|
|
})
|
|
return tmpVar
|
|
|
|
}
|
|
}
|
|
|
|
lhs := viaTmpVars(s.Lhs[0], "_val")
|
|
|
|
list = append(list, &ast.AssignStmt{
|
|
Lhs: []ast.Expr{lhs},
|
|
Tok: token.ASSIGN,
|
|
Rhs: []ast.Expr{
|
|
astutil.SetType(info, info.TypeOf(s.Lhs[0]), &ast.BinaryExpr{
|
|
X: lhs,
|
|
Op: op,
|
|
Y: astutil.SetType(info, info.TypeOf(s.Rhs[0]), &ast.ParenExpr{
|
|
X: s.Rhs[0],
|
|
}),
|
|
}),
|
|
},
|
|
})
|
|
|
|
return &ast.BlockStmt{
|
|
List: list,
|
|
}
|
|
}
|
|
return stmt
|
|
}
|