func TranspileFile(goFilename, phpFilename, phpStr string, gosrc io.Writer) error { parser := parser.NewParser() file, err := parser.Parse(phpFilename, phpStr) if err != nil { return fmt.Errorf("found errors while parsing %s: %s", phpFilename, err) } tg := Togo{currentScope: parser.FileSet.Scope} nodes := []goast.Node{} for _, node := range tg.beginScope(tg.currentScope) { nodes = append(nodes, node) } for _, phpNode := range file.Nodes { nodes = append(nodes, tg.ToGoStmt(phpNode.(phpast.Statement))) } buf := &bytes.Buffer{} if err = format.Node(buf, token.NewFileSet(), File(phpFilename[:len(phpFilename)-4], nodes...)); err != nil { return fmt.Errorf("error while formatting %s: %s", phpFilename, err) } imported, err := imports.Process(goFilename, buf.Bytes(), &imports.Options{AllErrors: true, Comments: true, TabIndent: true, TabWidth: 8}) if err != nil { return fmt.Errorf("error while getting imports for %s: %s", phpFilename, err) } _, err = gosrc.Write(imported) return err }
func TestDeadFunctions(t *testing.T) { src := `<?php $var1 = "a"; function simple() { $var2 = "b"; $var3 = "c"; } class fizz { const buzz = "fizzbuzz"; static function notsimple() { $var4 = "d"; } function other() {} } fizz::notsimple(); ` p := parser.NewParser() if _, err := p.Parse("test.php", src); err != nil { t.Fatal(err) } var shouldBeDead = map[string]struct{}{ "simple": struct{}{}, "other": struct{}{}, } dead := DeadFunctions(p.FileSet, []string{"test.php"}) for _, deadFunc := range dead { fnName := deadFunc.(*ast.FunctionStmt).Name if _, ok := shouldBeDead[fnName]; !ok { t.Error("%q was found dead, but shouldn't have been", fnName) } delete(shouldBeDead, fnName) } for fugitive, _ := range shouldBeDead { t.Error("%q should have been found dead, but wasn't", fugitive) } }
func TestDeadClass(t *testing.T) { src := `<?php class fizz { static function a() {} } class buzz { static function b() {} } class fizzbuzz { } fizz::notsimple(); $x = new fizzbuzz(); ` p := parser.NewParser() if _, err := p.Parse("test.php", src); err != nil { t.Fatal(err) } var shouldBeDead = map[string]struct{}{ "buzz": struct{}{}, } dead := DeadClasses(p.FileSet, []string{"test.php"}) for _, deadFunc := range dead { fnName := deadFunc.(*ast.Class).Name if _, ok := shouldBeDead[fnName]; !ok { t.Errorf("%q was found dead, but shouldn't have been", fnName) } delete(shouldBeDead, fnName) } for fugitive, _ := range shouldBeDead { t.Errorf("%q should have been found dead, but wasn't", fugitive) } }
func (g *gatherer) walkFile(path string, info os.FileInfo, err error) error { if info.IsDir() || !strings.HasSuffix(path, ".php") { return nil } if info.IsDir() && !g.recursive { return filepath.SkipDir } f, err := os.Open(path) if err != nil { return err } defer f.Close() src, err := ioutil.ReadAll(f) p := parser.NewParser() file, _ := p.Parse("test.php", string(src)) g.nodes = append(g.nodes, file.Nodes...) return nil }
func main() { flag.Parse() for _, arg := range flag.Args() { fmt.Println(arg) fmt.Println() src, err := ioutil.ReadFile(arg) if err != nil { fmt.Println(err) continue } p := printer.NewPrinter(os.Stdout) file, err := parser.NewParser().Parse("test.php", string(src)) if err != nil { log.Fatal(err) } for _, node := range file.Nodes { p.PrintNode(node) } } }
func TestPrinter(t *testing.T) { t.SkipNow() // disabling this test before some ast restructuring for _, test := range tests { p := parser.NewParser() file, err := p.Parse("test.php", test.Before) if err != nil { t.Error("parsing error:", err) continue } if len(file.Nodes) < 1 { continue } buf := &bytes.Buffer{} pr := NewPrinter(buf) pr.PrintNode(file.Nodes[0]) if buf.String() != test.After { t.Fatalf("formatted text did not match\nFormatted\n\n%s\n\nExpected\n\n%s\n", buf.String(), test.After) } } }
func main() { astonerror := flag.Bool("astonerror", false, "Print the AST on errors") ast := flag.Bool("ast", false, "Print the AST") showErrors := flag.Bool("showerrors", true, "show errors. If this is false, astonerror will be ignored") debugMode := flag.Bool("debug", false, "if true, panic on finding any error") cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file") verbose := flag.Bool("verbose", false, "print all filenames") flag.Parse() if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } var files, errors int for _, filename := range flag.Args() { if *verbose { fmt.Println(filename) } files += 1 fBytes, err := ioutil.ReadFile(filename) if err != nil { fmt.Println(err) continue } walker := printing.NewWalker() Parser := parser.NewParser() if *debugMode { Parser.Debug = true Parser.MaxErrors = 0 Parser.PrintTokens = true } file, err := Parser.Parse("test.php", string(fBytes)) nodes := file.Nodes if *ast && len(nodes) != 0 && nodes[0] != nil { for _, node := range nodes { walker.Walk(node) } } if err != nil { errors += 1 if *showErrors { if !*verbose { fmt.Println(filename) } if !*ast && *astonerror && len(nodes) != 0 && nodes[0] != nil { for _, node := range nodes { walker.Walk(node) } } fmt.Println(err) } } } fmt.Printf("Compiled %d files. %d files with errors - %f%% success\n", flag.NArg(), errors, 100*(1-(float64(errors)/float64(files)))) }