go: How can I get instantiated type with golang.org/x/tools/analysis?

Viewed 319

How can I get an instantiated generic type using golang.org/x/tools/analysis? I tried using instance map (pass.TypesInfo.Instances), but seems like I'm using a wrong *ast.Ident.

I tried using CallExpr.Fun.(*ast.Ident) as a key, but the map did not contain it.

(Also, I verified that map is not empty, by printing all elements of the map.)

// v is *ast.CallExpr from a type switch

callee := pass.TypesInfo.TypeOf(v.Fun)
if f, ok := callee.(*types.Signature); ok {
    f = expandGenerics(pass, v.Fun, f)
}

/// Super simple expander for generics
func expandGenerics(pass *analysis.Pass, callee ast.Expr, s *types.Signature) *types.Signature {
    if s.TypeParams() == nil {
        return s
    }

    if callee, ok := callee.(*ast.Ident); ok {
        log.Printf("Instance: %s\n", callee.Name)
        instance, ok := pass.TypesInfo.Instances[callee]

        if ok {
            log.Printf("Generic: %s\n", TypeString(pass.Pkg, instance.Type))

            if s, ok := instance.Type.(*types.Signature); ok {
                return s
            }

        } else {
            log.Printf("Unknown: %s\n", TypeString(pass.Pkg, s))

            //for key, ty := range pass.TypesInfo.Instances {
            //  log.Printf("Keys: %s (%s)\n", key, TypeString(pass.Pkg, ty.Type))
            //}
        }

    }

    return s
}


Edit:

I also checked for official source code. But strangely, it seems to use exactly same identifier as my code. https://github.com/golang/tools/blob/8865782bc0d76401a05a438cccb05486ca1e5c62/internal/lsp/source/inlay_hint.go#L201-L209

1 Answers

I found the cause. The input has a type mismatch in arguments so there was no ‘correct’ choice for the type parameter.

Actually, I was trying to fix the type mismatch using the first argument. I decided to manually instantiate.

Related