add normalisation pass (WIP)
This commit is contained in:
parent
94fe16f681
commit
6d9aa8b022
24
main.go
24
main.go
@ -33,25 +33,38 @@ func ConvertFile(filename string) (string, error) {
|
||||
// Enable comments extraction
|
||||
p.WithFreeFloating()
|
||||
|
||||
// Parse PHP content
|
||||
p.Parse()
|
||||
for _, err := range p.GetErrors() {
|
||||
return "", errors.New(err.String())
|
||||
}
|
||||
n := p.GetRootNode()
|
||||
|
||||
// Walk and print JSON...
|
||||
// Debug pass: Walk and print JSON...
|
||||
if fh, err := os.OpenFile(filename+`.parse.json`, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644); err == nil {
|
||||
v := visitor.NewPrettyJsonDumper(fh, namespaces)
|
||||
p.GetRootNode().Walk(v)
|
||||
n.Walk(v)
|
||||
fh.Close()
|
||||
}
|
||||
|
||||
// Walk and print (converted)
|
||||
ret, err := state.convert(p.GetRootNode())
|
||||
// Pass 1: Normalise Alt** Stmt types
|
||||
normPass := normaliseAltsPass{}
|
||||
n.Walk(&normPass) // can't modify root node, but that's fine
|
||||
|
||||
// Debug pass: Walk and print JSON...
|
||||
if fh, err := os.OpenFile(filename+`.parse2.json`, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644); err == nil {
|
||||
v := visitor.NewPrettyJsonDumper(fh, namespaces)
|
||||
n.Walk(v)
|
||||
fh.Close()
|
||||
}
|
||||
|
||||
// Pass 2: Walk and print (converted)
|
||||
ret, err := state.convert(n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Gofmt output
|
||||
// Pass 3: Gofmt output
|
||||
// TODO pass flags to get -s/-r equivalent for more agressive simplification
|
||||
formatted, err := format.Source([]byte(ret))
|
||||
if err != nil {
|
||||
@ -59,6 +72,7 @@ func ConvertFile(filename string) (string, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Done
|
||||
return string(formatted), nil
|
||||
}
|
||||
|
||||
|
101
normalisealts.go
Normal file
101
normalisealts.go
Normal file
@ -0,0 +1,101 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
//"io/ioutil"
|
||||
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
"github.com/z7zmey/php-parser/node/stmt"
|
||||
"github.com/z7zmey/php-parser/walker"
|
||||
)
|
||||
|
||||
type normaliseAltsPass struct {
|
||||
}
|
||||
|
||||
func (np *normaliseAltsPass) transformNonRecursive(n node.Node) (node.Node, bool) {
|
||||
|
||||
switch n := n.(type) {
|
||||
case *stmt.AltIf:
|
||||
// Build replacement node
|
||||
ifStmt := stmt.NewIf(n.Cond, n.Stmt, n.ElseIf, n.Else)
|
||||
ifStmt.FreeFloating = n.FreeFloating
|
||||
ifStmt.Position = n.Position
|
||||
// ifStmt has no .Attributes prop
|
||||
return ifStmt, true
|
||||
|
||||
case *stmt.AltElse:
|
||||
elseStmt := stmt.NewElse(n.Stmt)
|
||||
elseStmt.FreeFloating = n.FreeFloating
|
||||
elseStmt.Position = n.Position
|
||||
return elseStmt, true
|
||||
|
||||
case *stmt.AltElseIf:
|
||||
elifStmt := stmt.NewElseIf(n.Cond, n.Stmt)
|
||||
elifStmt.FreeFloating = n.FreeFloating
|
||||
elifStmt.Position = n.Position
|
||||
return elifStmt, true
|
||||
|
||||
default:
|
||||
return n, false // no change
|
||||
}
|
||||
}
|
||||
|
||||
func (np *normaliseAltsPass) walkMutateArray(stmts []node.Node) {
|
||||
for i, _ := range stmts {
|
||||
np.walkMutate(&stmts[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (np *normaliseAltsPass) walkMutate(child *node.Node) {
|
||||
|
||||
v2, didChange := np.transformNonRecursive(*child)
|
||||
if didChange {
|
||||
v2.Walk(np)
|
||||
*child = v2
|
||||
} else {
|
||||
(*child).Walk(np)
|
||||
}
|
||||
}
|
||||
|
||||
func (np *normaliseAltsPass) EnterNode(w walker.Walkable) bool {
|
||||
n, ok := w.(node.Node)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("Tried to walk non-node '%t'", w))
|
||||
}
|
||||
|
||||
// We need to override the .Walk() behaviour for all possible *parents*
|
||||
// of affected nodes. This is because the .Walk() interface does not give
|
||||
// us any opportunity to override single elements by the time we get there
|
||||
// Our custom Walk() implementation is not firing all EnterChildList/LeaveNode
|
||||
// visitors - but - that's fine since they're all noops anyway
|
||||
|
||||
switch n := n.(type) {
|
||||
case *stmt.StmtList:
|
||||
np.walkMutateArray(n.Stmts) // mutate slice in place
|
||||
return false // Signal not to use upstream .Walk() implementation
|
||||
|
||||
case *node.Root:
|
||||
np.walkMutateArray(n.Stmts) // mutate slice in place
|
||||
return false // Signal not to use upstream .Walk() implementation
|
||||
|
||||
case *stmt.AltIf:
|
||||
panic("altif")
|
||||
np.walkMutate(&n.Cond)
|
||||
np.walkMutateArray(n.ElseIf)
|
||||
np.walkMutate(&n.Else)
|
||||
return false
|
||||
|
||||
default:
|
||||
// No normalisation needed for this node type
|
||||
// Recurse deeper
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (np *normaliseAltsPass) LeaveNode(w walker.Walkable) {}
|
||||
func (np *normaliseAltsPass) EnterChildNode(key string, w walker.Walkable) {}
|
||||
func (np *normaliseAltsPass) LeaveChildNode(key string, w walker.Walkable) {}
|
||||
func (np *normaliseAltsPass) EnterChildList(key string, w walker.Walkable) {}
|
||||
func (np *normaliseAltsPass) LeaveChildList(key string, w walker.Walkable) {}
|
||||
|
||||
var _ walker.Visitor = &normaliseAltsPass{} // interface assertion
|
Loading…
Reference in New Issue
Block a user