github.com/golangci/go-tools@v0.0.0-20190318060251-af6baa5dc196/ssa/util.go (about)

     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  
     5  package ssa
     6  
     7  // This file defines a number of miscellaneous utility functions.
     8  
     9  import (
    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  
    22  func 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  //
    27  func 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.
    35  func isPointer(typ types.Type) bool {
    36  	_, ok := typ.Underlying().(*types.Pointer)
    37  	return ok
    38  }
    39  
    40  func isInterface(T types.Type) bool { return types.IsInterface(T) }
    41  
    42  // deref returns a pointer's element type; otherwise it returns typ.
    43  func 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.
    51  func recvType(obj *types.Func) types.Type {
    52  	return obj.Type().(*types.Signature).Recv().Type()
    53  }
    54  
    55  // DefaultType returns the default "typed" type for an "untyped" type;
    56  // it returns the incoming type for all other types.  The default type
    57  // for untyped nil is untyped nil.
    58  //
    59  // Exported to ssa/interp.
    60  //
    61  // TODO(adonovan): use go/types.DefaultType after 1.8.
    62  //
    63  func DefaultType(typ types.Type) types.Type {
    64  	if t, ok := typ.(*types.Basic); ok {
    65  		k := t.Kind()
    66  		switch k {
    67  		case types.UntypedBool:
    68  			k = types.Bool
    69  		case types.UntypedInt:
    70  			k = types.Int
    71  		case types.UntypedRune:
    72  			k = types.Rune
    73  		case types.UntypedFloat:
    74  			k = types.Float64
    75  		case types.UntypedComplex:
    76  			k = types.Complex128
    77  		case types.UntypedString:
    78  			k = types.String
    79  		}
    80  		typ = types.Typ[k]
    81  	}
    82  	return typ
    83  }
    84  
    85  // logStack prints the formatted "start" message to stderr and
    86  // returns a closure that prints the corresponding "end" message.
    87  // Call using 'defer logStack(...)()' to show builder stack on panic.
    88  // Don't forget trailing parens!
    89  //
    90  func logStack(format string, args ...interface{}) func() {
    91  	msg := fmt.Sprintf(format, args...)
    92  	io.WriteString(os.Stderr, msg)
    93  	io.WriteString(os.Stderr, "\n")
    94  	return func() {
    95  		io.WriteString(os.Stderr, msg)
    96  		io.WriteString(os.Stderr, " end\n")
    97  	}
    98  }
    99  
   100  // newVar creates a 'var' for use in a types.Tuple.
   101  func newVar(name string, typ types.Type) *types.Var {
   102  	return types.NewParam(token.NoPos, nil, name, typ)
   103  }
   104  
   105  // anonVar creates an anonymous 'var' for use in a types.Tuple.
   106  func anonVar(typ types.Type) *types.Var {
   107  	return newVar("", typ)
   108  }
   109  
   110  var lenResults = types.NewTuple(anonVar(tInt))
   111  
   112  // makeLen returns the len builtin specialized to type func(T)int.
   113  func makeLen(T types.Type) *Builtin {
   114  	lenParams := types.NewTuple(anonVar(T))
   115  	return &Builtin{
   116  		name: "len",
   117  		sig:  types.NewSignature(nil, lenParams, lenResults, false),
   118  	}
   119  }