func memberFromDecl(decl ast.Decl, imp *importer.Importer, consts []*string, funcs []*string, types []*string, vars []*string) ( []*string, []*string, []*string, []*string) { switch decl := decl.(type) { case *ast.GenDecl: // import, const, type or var switch decl.Tok { case token.CONST: for _, spec := range decl.Specs { for _, id := range spec.(*ast.ValueSpec).Names { if isExportedIdent(id) { consts = append(consts, &id.Name) } } } case token.VAR: for _, spec := range decl.Specs { for _, id := range spec.(*ast.ValueSpec).Names { if isExportedIdent(id) { vars = append(vars, &id.Name) } } } case token.TYPE: for _, spec := range decl.Specs { id := spec.(*ast.TypeSpec).Name if isExportedIdent(id) { types = append(types, &id.Name) } } } case *ast.FuncDecl: id := decl.Name if decl.Recv == nil && id.Name == "init" { return consts, funcs, types, vars } if isExportedIdent(id) && !strings.HasPrefix(id.Name, "Test") { // Can't handle receiver methods yet if decl.Recv == nil { filename := imp.Fset.File(decl.Pos()).Name() if !strings.HasSuffix(filename, "_test.go") { funcs = append(funcs, &id.Name) } } } } return consts, funcs, types, vars }
func (c *compiler) VisitDecl(decl ast.Decl) Value { c.setDebugLine(decl.Pos()) // This is temporary. We'll return errors later, rather than panicking. if c.Logger != nil { c.Logger.Println("Compile declaration:", c.fileset.Position(decl.Pos())) } defer func() { if e := recover(); e != nil { elist := new(scanner.ErrorList) elist.Add(c.fileset.Position(decl.Pos()), fmt.Sprint(e)) panic(elist) } }() switch x := decl.(type) { case *ast.FuncDecl: return c.VisitFuncDecl(x) case *ast.GenDecl: c.VisitGenDecl(x) return nil } panic(fmt.Sprintf("Unhandled decl (%s) at %s\n", reflect.TypeOf(decl), c.fileset.Position(decl.Pos()))) }
// getStructTypeDecl checks if the given decl is a type declaration for a // struct. If so, the TypeSpec is returned. func getStructTypeDecl(decl ast.Decl, fset *token.FileSet) (spec *ast.TypeSpec, found bool) { genDecl, ok := decl.(*ast.GenDecl) if !ok { return } if genDecl.Tok != token.TYPE { return } if len(genDecl.Specs) == 0 { revel.WARN.Printf("Surprising: %s:%d Decl contains no specifications", fset.Position(decl.Pos()).Filename, fset.Position(decl.Pos()).Line) return } spec = genDecl.Specs[0].(*ast.TypeSpec) _, found = spec.Type.(*ast.StructType) return }
func (f *File) validTopLevelDecl(decl ast.Decl) *Error { if decl == nil { return &Error{errors.New("Top level decl is nil"), 0} } if genDecl, ok := decl.(*ast.GenDecl); ok { if genDecl.Tok != token.IMPORT { return &Error{errors.New(fmt.Sprintf("Top level decl is not import statement or function declaration, decl:%v", genDecl)), genDecl.Pos()} } } else if funcDecl, ok := decl.(*ast.FuncDecl); ok { // Only functions (not methods) are allowed if funcDecl.Recv != nil { return &Error{errors.New("Only functions (not methods) are allowed"), funcDecl.Recv.Pos()} } if err := f.validFuncType(funcDecl.Type); err != nil { return err } if _, _, err := f.validFuncBody(funcDecl.Body); err != nil { return err } } else { return &Error{errors.New(fmt.Sprintf("Top level decl is not import statement or function declaration, decl:%v", decl)), decl.Pos()} } return nil }