node: bail out upon assignment inside if-expression
This commit is contained in:
parent
49241e7a8c
commit
315174c79a
@ -37,6 +37,8 @@ The goal is to produce idiomatic, maintainable Go code as part of a one-off conv
|
|||||||
[ ] Assignment expressions
|
[ ] Assignment expressions
|
||||||
- Go doesn't support assignment in rvalues, only as a statement
|
- Go doesn't support assignment in rvalues, only as a statement
|
||||||
- When walking below stmt level, need to first fully walk and check for any function calls + assignments that may need hoisting (and we can probably only do that correctly if there is no short-circuiting)
|
- When walking below stmt level, need to first fully walk and check for any function calls + assignments that may need hoisting (and we can probably only do that correctly if there is no short-circuiting)
|
||||||
|
- [X] Add subtree walk + catch error for this case
|
||||||
|
- [ ] Add hoisting pass
|
||||||
[ ] Closures
|
[ ] Closures
|
||||||
- [ ] Handle value/reference captures
|
- [ ] Handle value/reference captures
|
||||||
[ ] Sort callbacks
|
[ ] Sort callbacks
|
||||||
|
42
miniwalker.go
Normal file
42
miniwalker.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/z7zmey/php-parser/node"
|
||||||
|
"github.com/z7zmey/php-parser/walker"
|
||||||
|
)
|
||||||
|
|
||||||
|
type miniWalker struct {
|
||||||
|
cb func(node.Node) error
|
||||||
|
lastErr error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mw *miniWalker) EnterNode(w walker.Walkable) bool {
|
||||||
|
n, ok := w.(node.Node)
|
||||||
|
if !ok {
|
||||||
|
mw.lastErr = fmt.Errorf("Tried to walk non-node '%t'", w)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
err := mw.cb(n)
|
||||||
|
if err != nil {
|
||||||
|
mw.lastErr = err
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mw *miniWalker) LeaveNode(w walker.Walkable) {}
|
||||||
|
func (mw *miniWalker) EnterChildNode(key string, w walker.Walkable) {}
|
||||||
|
func (mw *miniWalker) LeaveChildNode(key string, w walker.Walkable) {}
|
||||||
|
func (mw *miniWalker) EnterChildList(key string, w walker.Walkable) {}
|
||||||
|
func (mw *miniWalker) LeaveChildList(key string, w walker.Walkable) {}
|
||||||
|
|
||||||
|
func walk(n node.Node, cb func(node.Node) error) error {
|
||||||
|
mw := miniWalker{cb: cb}
|
||||||
|
n.Walk(&mw)
|
||||||
|
|
||||||
|
return mw.lastErr
|
||||||
|
}
|
23
node.go
23
node.go
@ -511,6 +511,15 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
|
|||||||
return "fmt.Print(" + quoted + ")\n", nil // newline - standalone statement
|
return "fmt.Print(" + quoted + ")\n", nil // newline - standalone statement
|
||||||
|
|
||||||
case *stmt.If:
|
case *stmt.If:
|
||||||
|
|
||||||
|
hasCondAssign, err := hasInteriorAssignment(n.Cond)
|
||||||
|
if err != nil {
|
||||||
|
return "", parseErr{n, err}
|
||||||
|
}
|
||||||
|
if hasCondAssign {
|
||||||
|
return "", parseErr{n.Cond, fmt.Errorf("please remove assignment from if-expression")}
|
||||||
|
}
|
||||||
|
|
||||||
cond, err := this.convert(n.Cond)
|
cond, err := this.convert(n.Cond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", parseErr{n, err}
|
return "", parseErr{n, err}
|
||||||
@ -1158,3 +1167,17 @@ func (this *conversionState) convertFunctionCommon(params []node.Node, returnTyp
|
|||||||
// No extra trailing newline in case this is part of a large expression
|
// No extra trailing newline in case this is part of a large expression
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hasInteriorAssignment recursively walks a node, to determine if it contains
|
||||||
|
// any assignment expressions
|
||||||
|
func hasInteriorAssignment(n node.Node) (hasAnyAssign bool, err error) {
|
||||||
|
|
||||||
|
err = walk(n, func(n node.Node) error {
|
||||||
|
if _, ok := n.(*assign.Assign); ok {
|
||||||
|
hasAnyAssign = true
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return // named return
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user