type ( // An ImportSpec node represents a single package import. ImportSpec struct { Doc *CommentGroup // associated documentation; or nil Name *Ident // local package name (including "."); or nil Path *BasicLit // import path Comment *CommentGroup // line comments; or nil EndPos token.Pos // end of spec (overrides Path.Pos if nonzero) } // A ValueSpec node represents a constant or variable declaration // (ConstSpec or VarSpec production). // ValueSpec struct { Doc *CommentGroup // associated documentation; or nil Names []*Ident // value names (len(Names) > 0) Type Expr // value type; or nil Values []Expr // initial values; or nil Comment *CommentGroup // line comments; or nil } ) import ( "golang.org/x/tools/go/packages" ) a := 1 + 2
Step 3 Resolve the AST node to Type Info switch decl := node.(type) { case *ast.FuncDecl: // get the first receiver node receiver := decl.Recv.List[0] // pass the receiver type token to the type info map receiverTypeAndValue, ok := pkg.TypesInfo.Types[receiver.Type] if !ok { return true } // inspect the REAL type switch v := recvTV.Type.(type) { case *types.Named: // type A int case *types.Pointer: // *int } } 5ZQF"OE7BMVFDPOUBJOTUIFUZQFJOGPSNBUJPO VTFUIFUZQFJOGPSNBUJPOUPDIFDL
Step 5 reformat the code import ( "go/format" ) src, err := format.Source(buf.Bytes()) if err != nil { // Should never happen, but can arise when developing this code. // The user can compile the output to see the error. log.Printf("warning: internal error: invalid Go generated: %s", err) log.Printf("warning: compile the package to analyze the error") return buf.Bytes() } return src