func (tc *typechecker) declSignature(typ *ast.Type, recv, params, results *ast.FieldList) { assert((typ.Form == ast.Method) == (recv != nil)) typ.Params = ast.NewScope(nil) tc.declFields(typ.Params, recv, true) tc.declFields(typ.Params, params, true) typ.N = tc.declFields(typ.Params, results, true) }
func (tc *typechecker) typeFor(def *ast.Type, x ast.Expr, ref bool) (typ *ast.Type) { x = unparen(x) // type name if t, isIdent := x.(*ast.Ident); isIdent { obj := tc.find(t) if obj.Kind != ast.Typ { tc.Errorf(t.Pos(), "%s is not a type", t.Name) if def == nil { typ = ast.NewType(ast.BadType) } else { typ = def typ.Form = ast.BadType } typ.Expr = x return } if !ref { tc.resolve(obj) // check for cycles even if type resolved } typ = obj.Type if def != nil { // new type declaration: copy type structure def.Form = typ.Form def.N = typ.N def.Key, def.Elt = typ.Key, typ.Elt def.Params = typ.Params def.Expr = x typ = def } return } // type literal typ = def if typ == nil { typ = ast.NewType(ast.BadType) } typ.Expr = x switch t := x.(type) { case *ast.SelectorExpr: if debug { fmt.Println("qualified identifier unimplemented") } typ.Form = ast.BadType case *ast.StarExpr: typ.Form = ast.Pointer typ.Elt = tc.typeFor(nil, t.X, true) case *ast.ArrayType: if t.Len != nil { typ.Form = ast.Array // TODO(gri) compute the real length // (this may call resolve recursively) (*typ).N = 42 } else { typ.Form = ast.Slice } typ.Elt = tc.typeFor(nil, t.Elt, t.Len == nil) case *ast.StructType: typ.Form = ast.Struct tc.declFields(typ.Scope, t.Fields, false) case *ast.FuncType: typ.Form = ast.Function tc.declSignature(typ, nil, t.Params, t.Results) case *ast.InterfaceType: typ.Form = ast.Interface tc.declFields(typ.Scope, t.Methods, true) case *ast.MapType: typ.Form = ast.Map typ.Key = tc.typeFor(nil, t.Key, true) typ.Elt = tc.typeFor(nil, t.Value, true) case *ast.ChanType: typ.Form = ast.Channel typ.N = uint(t.Dir) typ.Elt = tc.typeFor(nil, t.Value, true) default: if debug { fmt.Printf("x is %T\n", x) } panic("unreachable") } return }