I have a simple example file:
==============================

package gobbledy_gook

import (
    "log"
    turtle "github.com/rs/zerolog/log"
    "os"
    "github.com/rs/zerolog"
)

var LOG = turtle.Logger.Output(os.Stdout).Error()

func g() []zerolog.Logger {
    return []zerolog.Logger{}
}

func DoThings()  {
    log.Println("proof of concept")
    g()[3].Error()
    return
}

==============================

I want to use go/ast & go/types to correctly identify the source code 
position of the turtle.Logger declaration (.../zerolog/log.go:13:5). 

If I parse only the gobbledy_gook package then the position ends up being 
<first file in FileSet>:1:9
If I parse gobbledy_gook & zerolog packages and put them in the fset / list 
of files I get an unexpected package error

Most of the below code is taken from the go/types#Info example code

func main() {
    files := make([]*ast.File, 0, 8)
    fset := token.NewFileSet()

    for _, dir := range []string{
        "../../test_package",
        "go/src/github.com/rs/zerolog",
        "go/src/github.com/rs/zerolog/log",
    } {
        packages, err := parser.ParseDir(fset, dir, nil, parser.AllErrors)
        if err != nil {
            fmt.Println(err)
            return
        }

        for _, p := range packages {
            for _, file := range p.Files {
                files = append(files, file)
            }
        }
    }
    fmt.Println("Parse complete")

    info := types.Info{
        Types: make(map[ast.Expr]types.TypeAndValue),
        Defs:  make(map[*ast.Ident]types.Object),
        Uses:  make(map[*ast.Ident]types.Object),
    }
    var conf types.Config = types.Config{Importer: importer.Default()}
    pkg, err := conf.Check("fib", fset, files, &info)
    if err != nil {
        log.Println(err.Error())
    }
    fmt.Println("Check complete")

    // Print package-level variables in initialization order.
    fmt.Printf("InitOrder: %v\n\n", info.InitOrder)

    // For each named object, print the line and
    // column of its definition and each of its uses.
    fmt.Println("Defs and Uses of each named object:")
    usesByObj := make(map[types.Object][]string)
    for id, obj := range info.Uses {
        posn := fset.Position(id.Pos())
        lineCol := fmt.Sprintf("%d:%d", posn.Line, posn.Column)
        usesByObj[obj] = append(usesByObj[obj], lineCol)
    }
    var items []string
    for obj, uses := range usesByObj {
        sort.Strings(uses)
        item := fmt.Sprintf("%s:\n  defined at %s\n  used at %s",
            types.ObjectString(obj, types.RelativeTo(pkg)),
            fset.Position(obj.Pos()),
            strings.Join(uses, ", "))
        items = append(items, item)
    }
    sort.Strings(items) // sort by line:col, in effect
    fmt.Println(strings.Join(items, "\n"))
    fmt.Println()

    fmt.Println("Types and Values of each expression:")
    items = nil
    for expr, tv := range info.Types {
        var buf bytes.Buffer
        posn := fset.Position(expr.Pos())
        tvstr := tv.Type.String()
        if tv.Value != nil {
            tvstr += " = " + tv.Value.String()
        }
        // line:col | expr | mode : type = value
        fmt.Fprintf(&buf, "%s:%2d:%2d | %-19s | %s", posn.Filename,
            posn.Line, posn.Column, types.ExprString(expr), tvstr)
        items = append(items, buf.String())
    }
    sort.Strings(items)
    fmt.Println(strings.Join(items, "\n"))
}

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to