func compilePackage(compiler llgo.Compiler, fset *token.FileSet, files map[string]*ast.File, importpath string) (*llgo.Module, error) { // make a package (resolve all identifiers) pkg, err := ast.NewPackage(fset, files, types.GcImport, types.Universe) if err != nil { report(err) return nil, err } // an empty importpath means the same as the package name if importpath == "" { importpath = pkg.Name } exprTypes, err := types.Check(importpath, compiler, fset, pkg) if err != nil { report(err) return nil, err } if *dumpast { ast.Fprint(os.Stderr, fset, pkg, nil) os.Exit(0) } return compiler.Compile(fset, pkg, importpath, exprTypes) }
func (f *file) debugRender(x interface{}) string { var buf bytes.Buffer if err := ast.Fprint(&buf, f.fset, x, nil); err != nil { panic(err) } return buf.String() }
func compilePackage(fset *token.FileSet, files map[string]*ast.File) (*llgo.Module, error) { // make a package (resolve all identifiers) pkg, err := ast.NewPackage(fset, files, types.GcImport, types.Universe) if err != nil { report(err) return nil, err } exprTypes, err := types.Check(fset, pkg) if err != nil { report(err) return nil, err } if *dumpast { ast.Fprint(os.Stderr, fset, pkg, nil) os.Exit(0) } compiler := llgo.NewCompiler() compiler.SetTraceEnabled(*trace) compiler.SetTargetArch(*arch) compiler.SetTargetOs(*os_) return compiler.Compile(fset, pkg, exprTypes) }
func main() { var filename string var src io.Reader var err error var astfile *ast.File fargs := flag.Args() if len(fargs) == 0 { filename = "-" src = os.Stdin } else if len(fargs) == 1 { filename = fargs[0] src, err = os.Open(filename) if err != nil { log.Fatal(err) } } else { fmt.Printf("usage: %s [-h] [options] [file]\n", path.Base(os.Args[0])) os.Exit(2) } fset := token.NewFileSet() astfile, err = parser.ParseFile(fset, filename, src, mode) if err != nil { log.Fatal(err) } if *astPrint { err = ast.Fprint(os.Stdout, fset, astfile, nil) if err != nil { log.Fatal(err) } } }
func (w *Walker) nodeDebug(node interface{}) string { if node == nil { return "" } var b bytes.Buffer ast.Fprint(&b, w.fset, node, nil) return b.String() }
func TestAddImport(t *testing.T) { for _, test := range addTests { file := parse(t, test.name, test.in) var before bytes.Buffer ast.Fprint(&before, fset, file, nil) AddNamedImport(fset, file, test.renamedPkg, test.pkg) if got := print(t, test.name, file); got != test.out { if test.broken { t.Logf("%s is known broken:\ngot: %s\nwant: %s", test.name, got, test.out) } else { t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out) } var after bytes.Buffer ast.Fprint(&after, fset, file, nil) t.Logf("AST before:\n%s\nAST after:\n%s\n", before.String(), after.String()) } } }
func Parse(filename string, source string) (a *Ast, dump string, err error) { // Create the AST by parsing src. fset := token.NewFileSet() // positions are relative to fset f, err := parser.ParseFile(fset, filename, source, 0) // Print the AST. var bf bytes.Buffer ast.Fprint(&bf, fset, f, ast.NotNilFilter) a, err = BuildAst("", f) if err != nil { return nil, "", err } return a, string(bf.Bytes()), nil }
func main() { var input io.Reader var err os.Error var filename string { temp := "a⍨c" fmt.Printf("Len: %v\n", len(temp)) for i := 0; i < len(temp); i++ { fmt.Printf("%3d: %02x\n", i, temp[i]) } } if flag.NArg() > 0 { filename = flag.Arg(0) if input, err = os.Open(flag.Arg(0)); err != nil { fmt.Print("Failed to open input: ", err) os.Exit(1) } } else { input = os.Stdin filename = "stdin" } var src_ast *ast.File fset := token.NewFileSet() src_ast, err = parser.ParseFile(fset, filename, input, parser.ParseComments) // | parser.Trace) if err != nil { panic(err) } Transform(src_ast) //dfa := CreateAutomata(source) outfile, err := os.Create(*output_file) if err != nil { fmt.Print("Failed to open output file: ", err) os.Exit(1) } //if err := printer.Fprint(outfile, fset, src_ast); err != nil { //fmt.Printf("%#v\n", src_ast) if _, err := ast.Fprint(outfile, fset, src_ast, nil); err != nil { fmt.Print("Write failed: ", err) os.Exit(1) } outfile.Close() }
func Example() { stmt, err := parserutil.ParseStmt("var x int") if err != nil { panic(err) } ast.Fprint(os.Stdout, nil, stmt, nil) // Output: // 0 *ast.DeclStmt { // 1 . Decl: *ast.GenDecl { // 2 . . Doc: nil // 3 . . TokPos: 31 // 4 . . Tok: var // 5 . . Lparen: 0 // 6 . . Specs: []ast.Spec (len = 1) { // 7 . . . 0: *ast.ValueSpec { // 8 . . . . Doc: nil // 9 . . . . Names: []*ast.Ident (len = 1) { // 10 . . . . . 0: *ast.Ident { // 11 . . . . . . NamePos: 35 // 12 . . . . . . Name: "x" // 13 . . . . . . Obj: *ast.Object { // 14 . . . . . . . Kind: var // 15 . . . . . . . Name: "x" // 16 . . . . . . . Decl: *(obj @ 7) // 17 . . . . . . . Data: 0 // 18 . . . . . . . Type: nil // 19 . . . . . . } // 20 . . . . . } // 21 . . . . } // 22 . . . . Type: *ast.Ident { // 23 . . . . . NamePos: 37 // 24 . . . . . Name: "int" // 25 . . . . . Obj: nil // 26 . . . . } // 27 . . . . Values: nil // 28 . . . . Comment: nil // 29 . . . } // 30 . . } // 31 . . Rparen: 0 // 32 . } // 33 } }
func main() { if len(os.Args) != 2 { fmt.Printf("usage: astprint <filename.go>\n") return } // Создаём хранилище данных об исходных файлах fset := token.NewFileSet() // Вызываем парсер if file, err := parser.ParseFile( fset, // данные об исходниках os.Args[1], // имя файла с исходником программы nil, // пусть парсер сам загрузит исходник parser.ParseComments, // приказываем сохранять комментарии ); err == nil { // Если парсер отработал без ошибок, печатаем дерево ast.Fprint(os.Stdout, fset, file, nil) } else { // в противном случае, выводим сообщение об ошибке fmt.Printf("Error: %v", err) } }
func Process(filename string) (pkg string, mocks []*Mock, err os.Error) { fset := token.NewFileSet() file, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) if err != nil { return "", nil, err } var toString func(interface{}) string toString = func(x interface{}) (str string) { switch x := x.(type) { case *ast.BasicLit: return x.Value case *ast.Ident: return x.Name case *ast.ArrayType: return "[" + toString(x.Len) + "]" + toString(x.Elt) case *ast.MapType: return "map[" + toString(x.Key) + "]" + toString(x.Value) case *ast.SelectorExpr: return toString(x.X) + "." + toString(x.Sel) case nil: return "" default: // TODO(kevlar): Ellipsis (variadic functions) fmt.Fprintf(os.Stderr, "Unable to determine string for %T:\n", x) ast.Fprint(os.Stderr, fset, x, nil) } return "unknown" } pkg = toString(file.Name) for _, decl := range file.Decls { if gen, ok := decl.(*ast.GenDecl); ok && gen.Tok == token.TYPE { for _, spec := range gen.Specs { if tspec, ok := spec.(*ast.TypeSpec); ok { if iface, ok := tspec.Type.(*ast.InterfaceType); ok { mock := &Mock{ Name: toString(tspec.Name), } mocks = append(mocks, mock) for _, method := range iface.Methods.List { meth := &Method{ Name: toString(method.Names[0]), } mock.Methods = append(mock.Methods, meth) if f, ok := method.Type.(*ast.FuncType); ok { if f.Params != nil { for _, param := range f.Params.List { meth.Params = append(meth.Params, toString(param.Type)) } } if f.Results != nil { for _, ret := range f.Results.List { meth.Returns = append(meth.Returns, toString(ret.Type)) } } } } } } } } } return }
func oneFile(dir, s string, fset *token.FileSet, f *ast.File) error { // Inspect the AST and change all instances of main() isMain := false ast.Inspect(f, func(n ast.Node) bool { switch x := n.(type) { case *ast.File: x.Name.Name = config.CmdName case *ast.FuncDecl: if x.Name.Name == "main" { x.Name.Name = fmt.Sprintf("Main") // Append a return. x.Body.List = append(x.Body.List, &ast.ReturnStmt{}) isMain = true } case *ast.CallExpr: debug("%v %v\n", reflect.TypeOf(n), n) switch z := x.Fun.(type) { case *ast.SelectorExpr: // somebody tell me how to do this. sel := fmt.Sprintf("%v", z.X) // TODO: Need to have fixFlag and fixFlagVar // as the Var variation has name in the SECOND argument. if sel == "flag" { if ix, ok := fixFlag[z.Sel.Name]; ok { switch zz := x.Args[ix].(type) { case *ast.BasicLit: zz.Value = "\"" + config.CmdName + "." + zz.Value[1:] } } } } } return true }) if *dumpAST { ast.Fprint(os.Stderr, fset, f, nil) } var buf bytes.Buffer if err := format.Node(&buf, fset, f); err != nil { panic(err) } debug("%s", buf.Bytes()) out := string(buf.Bytes()) // fix up any imports. We may have forced the issue // with os.Args opts := imports.Options{ Fragment: true, AllErrors: true, Comments: true, TabIndent: true, TabWidth: 8, } fullCode, err := imports.Process("commandline", []byte(out), &opts) if err != nil { log.Fatalf("bad parse: '%v': %v", out, err) } of := path.Join(dir, path.Base(s)) if err := ioutil.WriteFile(of, []byte(fullCode), 0666); err != nil { log.Fatalf("%v\n", err) } // fun: must write the file first so the import fixup works :-) if isMain { // Write the file to interface to the command package. t := template.Must(template.New("cmdFunc").Parse(cmdFunc)) var b bytes.Buffer if err := t.Execute(&b, config); err != nil { log.Fatalf("spec %v: %v\n", cmdFunc, err) } fullCode, err := imports.Process("commandline", []byte(b.Bytes()), &opts) if err != nil { log.Fatalf("bad parse: '%v': %v", out, err) } if err := ioutil.WriteFile(path.Join(config.Bbsh, "cmd_"+config.CmdName+".go"), fullCode, 0444); err != nil { log.Fatalf("%v\n", err) } } return nil }
func createAstFileDump(filename string, fileSet *token.FileSet, astFile *ast.File) { file, err := os.Create(filename) util.PanicOnError(err) defer file.Close() ast.Fprint(file, fileSet, astFile, ast.NotNilFilter) }
func printNode(n ast.Node) { var w bytes.Buffer ast.Fprint(&w, nil, n, nil) fmt.Printf(w.String()) }