* Update to latest x/tools (2020/01/19). Fixes #893 * Initialize vet analyzers as unexportd global vars. Fixes #915 * Support testing Go 1.14beta1. * ci: reset go.mod and go.sum before generated diff check * Update to latest x/tools (2020/02/04) Co-authored-by: Aleksandr Razumov <ar@gortc.io>
		
			
				
	
	
		
			90 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2013 The Go Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package ssa
 | 
						|
 | 
						|
// This file defines a number of miscellaneous utility functions.
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"go/ast"
 | 
						|
	"go/token"
 | 
						|
	"go/types"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
 | 
						|
	"golang.org/x/tools/go/ast/astutil"
 | 
						|
)
 | 
						|
 | 
						|
//// AST utilities
 | 
						|
 | 
						|
func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) }
 | 
						|
 | 
						|
// isBlankIdent returns true iff e is an Ident with name "_".
 | 
						|
// They have no associated types.Object, and thus no type.
 | 
						|
//
 | 
						|
func isBlankIdent(e ast.Expr) bool {
 | 
						|
	id, ok := e.(*ast.Ident)
 | 
						|
	return ok && id.Name == "_"
 | 
						|
}
 | 
						|
 | 
						|
//// Type utilities.  Some of these belong in go/types.
 | 
						|
 | 
						|
// isPointer returns true for types whose underlying type is a pointer.
 | 
						|
func isPointer(typ types.Type) bool {
 | 
						|
	_, ok := typ.Underlying().(*types.Pointer)
 | 
						|
	return ok
 | 
						|
}
 | 
						|
 | 
						|
func isInterface(T types.Type) bool { return types.IsInterface(T) }
 | 
						|
 | 
						|
// deref returns a pointer's element type; otherwise it returns typ.
 | 
						|
func deref(typ types.Type) types.Type {
 | 
						|
	if p, ok := typ.Underlying().(*types.Pointer); ok {
 | 
						|
		return p.Elem()
 | 
						|
	}
 | 
						|
	return typ
 | 
						|
}
 | 
						|
 | 
						|
// recvType returns the receiver type of method obj.
 | 
						|
func recvType(obj *types.Func) types.Type {
 | 
						|
	return obj.Type().(*types.Signature).Recv().Type()
 | 
						|
}
 | 
						|
 | 
						|
// logStack prints the formatted "start" message to stderr and
 | 
						|
// returns a closure that prints the corresponding "end" message.
 | 
						|
// Call using 'defer logStack(...)()' to show builder stack on panic.
 | 
						|
// Don't forget trailing parens!
 | 
						|
//
 | 
						|
func logStack(format string, args ...interface{}) func() {
 | 
						|
	msg := fmt.Sprintf(format, args...)
 | 
						|
	io.WriteString(os.Stderr, msg)
 | 
						|
	io.WriteString(os.Stderr, "\n")
 | 
						|
	return func() {
 | 
						|
		io.WriteString(os.Stderr, msg)
 | 
						|
		io.WriteString(os.Stderr, " end\n")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// newVar creates a 'var' for use in a types.Tuple.
 | 
						|
func newVar(name string, typ types.Type) *types.Var {
 | 
						|
	return types.NewParam(token.NoPos, nil, name, typ)
 | 
						|
}
 | 
						|
 | 
						|
// anonVar creates an anonymous 'var' for use in a types.Tuple.
 | 
						|
func anonVar(typ types.Type) *types.Var {
 | 
						|
	return newVar("", typ)
 | 
						|
}
 | 
						|
 | 
						|
var lenResults = types.NewTuple(anonVar(tInt))
 | 
						|
 | 
						|
// makeLen returns the len builtin specialized to type func(T)int.
 | 
						|
func makeLen(T types.Type) *Builtin {
 | 
						|
	lenParams := types.NewTuple(anonVar(T))
 | 
						|
	return &Builtin{
 | 
						|
		name: "len",
 | 
						|
		sig:  types.NewSignature(nil, lenParams, lenResults, false),
 | 
						|
	}
 | 
						|
}
 |