package types
import (
"go/ast"
"go/constant"
)
func (check *Checker ) record (x *operand ) {
var typ Type
var val constant .Value
switch x .mode {
case invalid :
typ = Typ [Invalid ]
case novalue :
typ = (*Tuple )(nil )
case constant_ :
typ = x .typ
val = x .val
default :
typ = x .typ
}
assert (x .expr != nil && typ != nil )
if isUntyped (typ ) {
check .rememberUntyped (x .expr , false , x .mode , typ .(*Basic ), val )
} else {
check .recordTypeAndValue (x .expr , x .mode , typ , val )
}
}
func (check *Checker ) recordUntyped () {
if !debug && !check .recordTypes () {
return
}
for x , info := range check .untyped {
if debug && isTyped (info .typ ) {
check .dump ("%v: %s (type %s) is typed" , x .Pos (), x , info .typ )
panic ("unreachable" )
}
check .recordTypeAndValue (x , info .mode , info .typ , info .val )
}
}
func (check *Checker ) recordTypeAndValue (x ast .Expr , mode operandMode , typ Type , val constant .Value ) {
assert (x != nil )
assert (typ != nil )
if mode == invalid {
return
}
if mode == constant_ {
assert (val != nil )
assert (!isValid (typ ) || allBasic (typ , IsConstType ))
}
if m := check .Types ; m != nil {
m [x ] = TypeAndValue {mode , typ , val }
}
check .recordTypeAndValueInSyntax (x , mode , typ , val )
}
func (check *Checker ) recordBuiltinType (f ast .Expr , sig *Signature ) {
for {
check .recordTypeAndValue (f , builtin , sig , nil )
switch p := f .(type ) {
case *ast .Ident , *ast .SelectorExpr :
return
case *ast .ParenExpr :
f = p .X
default :
panic ("unreachable" )
}
}
}
func (check *Checker ) recordCommaOkTypes (x ast .Expr , a []*operand ) {
assert (x != nil )
assert (len (a ) == 2 )
if a [0 ].mode == invalid {
return
}
t0 , t1 := a [0 ].typ , a [1 ].typ
assert (isTyped (t0 ) && isTyped (t1 ) && (allBoolean (t1 ) || t1 == universeError ))
if m := check .Types ; m != nil {
for {
tv := m [x ]
assert (tv .Type != nil )
pos := x .Pos ()
tv .Type = NewTuple (
NewVar (pos , check .pkg , "" , t0 ),
NewVar (pos , check .pkg , "" , t1 ),
)
m [x ] = tv
p , _ := x .(*ast .ParenExpr )
if p == nil {
break
}
x = p .X
}
}
check .recordCommaOkTypesInSyntax (x , t0 , t1 )
}
func (check *Checker ) recordInstance (expr ast .Expr , targs []Type , typ Type ) {
ident := instantiatedIdent (expr )
assert (ident != nil )
assert (typ != nil )
if m := check .Instances ; m != nil {
m [ident ] = Instance {newTypeList (targs ), typ }
}
}
func (check *Checker ) recordDef (id *ast .Ident , obj Object ) {
assert (id != nil )
if m := check .Defs ; m != nil {
m [id ] = obj
}
}
func (check *Checker ) recordUse (id *ast .Ident , obj Object ) {
assert (id != nil )
assert (obj != nil )
if m := check .Uses ; m != nil {
m [id ] = obj
}
}
func (check *Checker ) recordImplicit (node ast .Node , obj Object ) {
assert (node != nil )
assert (obj != nil )
if m := check .Implicits ; m != nil {
m [node ] = obj
}
}
func (check *Checker ) recordSelection (x *ast .SelectorExpr , kind SelectionKind , recv Type , obj Object , index []int , indirect bool ) {
assert (obj != nil && (recv == nil || len (index ) > 0 ))
check .recordUse (x .Sel , obj )
if m := check .Selections ; m != nil {
m [x ] = &Selection {kind , recv , obj , index , indirect }
}
}
func (check *Checker ) recordScope (node ast .Node , scope *Scope ) {
assert (node != nil )
assert (scope != nil )
if m := check .Scopes ; m != nil {
m [node ] = scope
}
}
The pages are generated with Golds v0.7.3-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .