[CI] Add more checks (#43)
This commit is contained in:
169
vendor/honnef.co/go/tools/ssa/const.go
vendored
Normal file
169
vendor/honnef.co/go/tools/ssa/const.go
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
// 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 the Const SSA value type.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
exact "go/constant"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// NewConst returns a new constant of the specified value and type.
|
||||
// val must be valid according to the specification of Const.Value.
|
||||
//
|
||||
func NewConst(val exact.Value, typ types.Type) *Const {
|
||||
return &Const{typ, val}
|
||||
}
|
||||
|
||||
// intConst returns an 'int' constant that evaluates to i.
|
||||
// (i is an int64 in case the host is narrower than the target.)
|
||||
func intConst(i int64) *Const {
|
||||
return NewConst(exact.MakeInt64(i), tInt)
|
||||
}
|
||||
|
||||
// nilConst returns a nil constant of the specified type, which may
|
||||
// be any reference type, including interfaces.
|
||||
//
|
||||
func nilConst(typ types.Type) *Const {
|
||||
return NewConst(nil, typ)
|
||||
}
|
||||
|
||||
// stringConst returns a 'string' constant that evaluates to s.
|
||||
func stringConst(s string) *Const {
|
||||
return NewConst(exact.MakeString(s), tString)
|
||||
}
|
||||
|
||||
// zeroConst returns a new "zero" constant of the specified type,
|
||||
// which must not be an array or struct type: the zero values of
|
||||
// aggregates are well-defined but cannot be represented by Const.
|
||||
//
|
||||
func zeroConst(t types.Type) *Const {
|
||||
switch t := t.(type) {
|
||||
case *types.Basic:
|
||||
switch {
|
||||
case t.Info()&types.IsBoolean != 0:
|
||||
return NewConst(exact.MakeBool(false), t)
|
||||
case t.Info()&types.IsNumeric != 0:
|
||||
return NewConst(exact.MakeInt64(0), t)
|
||||
case t.Info()&types.IsString != 0:
|
||||
return NewConst(exact.MakeString(""), t)
|
||||
case t.Kind() == types.UnsafePointer:
|
||||
fallthrough
|
||||
case t.Kind() == types.UntypedNil:
|
||||
return nilConst(t)
|
||||
default:
|
||||
panic(fmt.Sprint("zeroConst for unexpected type:", t))
|
||||
}
|
||||
case *types.Pointer, *types.Slice, *types.Interface, *types.Chan, *types.Map, *types.Signature:
|
||||
return nilConst(t)
|
||||
case *types.Named:
|
||||
return NewConst(zeroConst(t.Underlying()).Value, t)
|
||||
case *types.Array, *types.Struct, *types.Tuple:
|
||||
panic(fmt.Sprint("zeroConst applied to aggregate:", t))
|
||||
}
|
||||
panic(fmt.Sprint("zeroConst: unexpected ", t))
|
||||
}
|
||||
|
||||
func (c *Const) RelString(from *types.Package) string {
|
||||
var s string
|
||||
if c.Value == nil {
|
||||
s = "nil"
|
||||
} else if c.Value.Kind() == exact.String {
|
||||
s = exact.StringVal(c.Value)
|
||||
const max = 20
|
||||
// TODO(adonovan): don't cut a rune in half.
|
||||
if len(s) > max {
|
||||
s = s[:max-3] + "..." // abbreviate
|
||||
}
|
||||
s = strconv.Quote(s)
|
||||
} else {
|
||||
s = c.Value.String()
|
||||
}
|
||||
return s + ":" + relType(c.Type(), from)
|
||||
}
|
||||
|
||||
func (c *Const) Name() string {
|
||||
return c.RelString(nil)
|
||||
}
|
||||
|
||||
func (c *Const) String() string {
|
||||
return c.Name()
|
||||
}
|
||||
|
||||
func (c *Const) Type() types.Type {
|
||||
return c.typ
|
||||
}
|
||||
|
||||
func (c *Const) Referrers() *[]Instruction {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Const) Parent() *Function { return nil }
|
||||
|
||||
func (c *Const) Pos() token.Pos {
|
||||
return token.NoPos
|
||||
}
|
||||
|
||||
// IsNil returns true if this constant represents a typed or untyped nil value.
|
||||
func (c *Const) IsNil() bool {
|
||||
return c.Value == nil
|
||||
}
|
||||
|
||||
// TODO(adonovan): move everything below into honnef.co/go/tools/ssa/interp.
|
||||
|
||||
// Int64 returns the numeric value of this constant truncated to fit
|
||||
// a signed 64-bit integer.
|
||||
//
|
||||
func (c *Const) Int64() int64 {
|
||||
switch x := exact.ToInt(c.Value); x.Kind() {
|
||||
case exact.Int:
|
||||
if i, ok := exact.Int64Val(x); ok {
|
||||
return i
|
||||
}
|
||||
return 0
|
||||
case exact.Float:
|
||||
f, _ := exact.Float64Val(x)
|
||||
return int64(f)
|
||||
}
|
||||
panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
|
||||
}
|
||||
|
||||
// Uint64 returns the numeric value of this constant truncated to fit
|
||||
// an unsigned 64-bit integer.
|
||||
//
|
||||
func (c *Const) Uint64() uint64 {
|
||||
switch x := exact.ToInt(c.Value); x.Kind() {
|
||||
case exact.Int:
|
||||
if u, ok := exact.Uint64Val(x); ok {
|
||||
return u
|
||||
}
|
||||
return 0
|
||||
case exact.Float:
|
||||
f, _ := exact.Float64Val(x)
|
||||
return uint64(f)
|
||||
}
|
||||
panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
|
||||
}
|
||||
|
||||
// Float64 returns the numeric value of this constant truncated to fit
|
||||
// a float64.
|
||||
//
|
||||
func (c *Const) Float64() float64 {
|
||||
f, _ := exact.Float64Val(c.Value)
|
||||
return f
|
||||
}
|
||||
|
||||
// Complex128 returns the complex value of this constant truncated to
|
||||
// fit a complex128.
|
||||
//
|
||||
func (c *Const) Complex128() complex128 {
|
||||
re, _ := exact.Float64Val(exact.Real(c.Value))
|
||||
im, _ := exact.Float64Val(exact.Imag(c.Value))
|
||||
return complex(re, im)
|
||||
}
|
Reference in New Issue
Block a user