1// Copyright 2013 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package ir 6 7// This file defines a number of miscellaneous utility functions. 8 9import ( 10 "fmt" 11 "go/ast" 12 "go/token" 13 "go/types" 14 "io" 15 "os" 16 17 "golang.org/x/tools/go/ast/astutil" 18) 19 20//// AST utilities 21 22func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } 23 24// isBlankIdent returns true iff e is an Ident with name "_". 25// They have no associated types.Object, and thus no type. 26// 27func isBlankIdent(e ast.Expr) bool { 28 id, ok := e.(*ast.Ident) 29 return ok && id.Name == "_" 30} 31 32//// Type utilities. Some of these belong in go/types. 33 34// isPointer returns true for types whose underlying type is a pointer. 35func isPointer(typ types.Type) bool { 36 _, ok := typ.Underlying().(*types.Pointer) 37 return ok 38} 39 40func isInterface(T types.Type) bool { return types.IsInterface(T) } 41 42// deref returns a pointer's element type; otherwise it returns typ. 43func deref(typ types.Type) types.Type { 44 if p, ok := typ.Underlying().(*types.Pointer); ok { 45 return p.Elem() 46 } 47 return typ 48} 49 50// recvType returns the receiver type of method obj. 51func recvType(obj *types.Func) types.Type { 52 return obj.Type().(*types.Signature).Recv().Type() 53} 54 55// logStack prints the formatted "start" message to stderr and 56// returns a closure that prints the corresponding "end" message. 57// Call using 'defer logStack(...)()' to show builder stack on panic. 58// Don't forget trailing parens! 59// 60func logStack(format string, args ...interface{}) func() { 61 msg := fmt.Sprintf(format, args...) 62 io.WriteString(os.Stderr, msg) 63 io.WriteString(os.Stderr, "\n") 64 return func() { 65 io.WriteString(os.Stderr, msg) 66 io.WriteString(os.Stderr, " end\n") 67 } 68} 69 70// newVar creates a 'var' for use in a types.Tuple. 71func newVar(name string, typ types.Type) *types.Var { 72 return types.NewParam(token.NoPos, nil, name, typ) 73} 74 75// anonVar creates an anonymous 'var' for use in a types.Tuple. 76func anonVar(typ types.Type) *types.Var { 77 return newVar("", typ) 78} 79 80var lenResults = types.NewTuple(anonVar(tInt)) 81 82// makeLen returns the len builtin specialized to type func(T)int. 83func makeLen(T types.Type) *Builtin { 84 lenParams := types.NewTuple(anonVar(T)) 85 return &Builtin{ 86 name: "len", 87 sig: types.NewSignature(nil, lenParams, lenResults, false), 88 } 89} 90