package main import ( "errors" "flag" "fmt" "go/format" "io/ioutil" "os" "github.com/z7zmey/php-parser/parser" "github.com/z7zmey/php-parser/visitor" "php2go/parseutil" ) const ( phpVersionMajor = 7 phpVersionMinor = 4 phpVersionPatch = 0 phpVersionExtra = `-php2go` ) func ConvertFile(filename string) (string, error) { inputFile, err := ioutil.ReadFile(filename) if err != nil { return "", err } namespaces := visitor.NewNamespaceResolver() // scope := NewScope() state := conversionState{ importPackages: make(map[string]struct{}), } p, err := parser.NewParser([]byte(inputFile), fmt.Sprintf("%d.%d", phpVersionMajor, phpVersionMinor)) if err != nil { panic(err) } // Enable comments extraction p.WithFreeFloating() // Parse PHP content p.Parse() for _, err := range p.GetErrors() { return "", errors.New(err.String()) } n := p.GetRootNode() // 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) n.Walk(v) fh.Close() } // Pass 1: Normalise Alt** Stmt types normaliser := parseutil.MutatingWalker{ EnterNode: normaliseAltCb, LeaveNode: parseutil.MutatingWalkerNoop, } err = normaliser.Walk(&n) if err != nil { return "", err } // Pass 1.5: Hoist some expressions out of rvalue contexts err = runHoistPass(&n) if err != nil { return "", err } // 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 } // 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 { ret += "// Gofmt failed: " + err.Error() return ret, nil } // Done return string(formatted), nil } func main() { filename := flag.String("InFile", "", "Select file to convert") flag.Parse() ret, err := ConvertFile(*filename) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } fmt.Println(ret) }