diff options
| author | Joseph Richey <joerichey94@gmail.com> | 2018-02-11 20:34:07 -0800 |
|---|---|---|
| committer | Joseph Richey <joerichey94@gmail.com> | 2018-02-11 20:34:07 -0800 |
| commit | 23b8c7b4eab0375b3d59cf4b2a1f3d7356515f95 (patch) | |
| tree | 6ec67f8d6b15420c3870d2b7c43b2b636fbb8349 /vendor/honnef.co/go/tools/functions/concrete.go | |
| parent | fff13ea9041a3945e36d5f002c3c0a1e0e93c825 (diff) | |
vendor: include source for tools
This change vendors the source for all our build, formatting, and
linting tools. Generated by running "dep ensure".
Diffstat (limited to 'vendor/honnef.co/go/tools/functions/concrete.go')
| -rw-r--r-- | vendor/honnef.co/go/tools/functions/concrete.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/vendor/honnef.co/go/tools/functions/concrete.go b/vendor/honnef.co/go/tools/functions/concrete.go new file mode 100644 index 0000000..932acd0 --- /dev/null +++ b/vendor/honnef.co/go/tools/functions/concrete.go @@ -0,0 +1,56 @@ +package functions + +import ( + "go/token" + "go/types" + + "honnef.co/go/tools/ssa" +) + +func concreteReturnTypes(fn *ssa.Function) []*types.Tuple { + res := fn.Signature.Results() + if res == nil { + return nil + } + ifaces := make([]bool, res.Len()) + any := false + for i := 0; i < res.Len(); i++ { + _, ifaces[i] = res.At(i).Type().Underlying().(*types.Interface) + any = any || ifaces[i] + } + if !any { + return []*types.Tuple{res} + } + var out []*types.Tuple + for _, block := range fn.Blocks { + if len(block.Instrs) == 0 { + continue + } + ret, ok := block.Instrs[len(block.Instrs)-1].(*ssa.Return) + if !ok { + continue + } + vars := make([]*types.Var, res.Len()) + for i, v := range ret.Results { + var typ types.Type + if !ifaces[i] { + typ = res.At(i).Type() + } else if mi, ok := v.(*ssa.MakeInterface); ok { + // TODO(dh): if mi.X is a function call that returns + // an interface, call concreteReturnTypes on that + // function (or, really, go through Descriptions, + // avoid infinite recursion etc, just like nil error + // detection) + + // TODO(dh): support Phi nodes + typ = mi.X.Type() + } else { + typ = res.At(i).Type() + } + vars[i] = types.NewParam(token.NoPos, nil, "", typ) + } + out = append(out, types.NewTuple(vars...)) + } + // TODO(dh): deduplicate out + return out +} |