Esempio n. 1
0
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
}
Esempio n. 2
0
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)
	}
}
Esempio n. 3
0
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)
	}
}
Esempio n. 4
0
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
}
Esempio n. 5
0
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)
		}
	}
}
Esempio n. 6
0
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)
		}
	}
}
Esempio n. 7
0
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))))
}