github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/src/go/types/universe.go (about) 1 // Copyright 2011 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 // This file sets up the universe scope and the unsafe package. 6 7 package types 8 9 import ( 10 "go/constant" 11 "go/token" 12 "strings" 13 ) 14 15 var ( 16 Universe *Scope 17 Unsafe *Package 18 universeIota *Const 19 universeByte *Basic // uint8 alias, but has name "byte" 20 universeRune *Basic // int32 alias, but has name "rune" 21 ) 22 23 var Typ = []*Basic{ 24 Invalid: {Invalid, 0, "invalid type"}, 25 26 Bool: {Bool, IsBoolean, "bool"}, 27 Int: {Int, IsInteger, "int"}, 28 Int8: {Int8, IsInteger, "int8"}, 29 Int16: {Int16, IsInteger, "int16"}, 30 Int32: {Int32, IsInteger, "int32"}, 31 Int64: {Int64, IsInteger, "int64"}, 32 Uint: {Uint, IsInteger | IsUnsigned, "uint"}, 33 Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"}, 34 Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"}, 35 Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"}, 36 Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"}, 37 Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"}, 38 Float32: {Float32, IsFloat, "float32"}, 39 Float64: {Float64, IsFloat, "float64"}, 40 Complex64: {Complex64, IsComplex, "complex64"}, 41 Complex128: {Complex128, IsComplex, "complex128"}, 42 String: {String, IsString, "string"}, 43 UnsafePointer: {UnsafePointer, 0, "Pointer"}, 44 45 UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"}, 46 UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"}, 47 UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"}, 48 UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"}, 49 UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"}, 50 UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"}, 51 UntypedNil: {UntypedNil, IsUntyped, "untyped nil"}, 52 } 53 54 var aliases = [...]*Basic{ 55 {Byte, IsInteger | IsUnsigned, "byte"}, 56 {Rune, IsInteger, "rune"}, 57 } 58 59 func defPredeclaredTypes() { 60 for _, t := range Typ { 61 def(NewTypeName(token.NoPos, nil, t.name, t)) 62 } 63 for _, t := range aliases { 64 def(NewTypeName(token.NoPos, nil, t.name, t)) 65 } 66 67 // Error has a nil package in its qualified name since it is in no package 68 res := NewVar(token.NoPos, nil, "", Typ[String]) 69 sig := &Signature{results: NewTuple(res)} 70 err := NewFunc(token.NoPos, nil, "Error", sig) 71 typ := &Named{underlying: NewInterface([]*Func{err}, nil).Complete()} 72 sig.recv = NewVar(token.NoPos, nil, "", typ) 73 def(NewTypeName(token.NoPos, nil, "error", typ)) 74 } 75 76 var predeclaredConsts = [...]struct { 77 name string 78 kind BasicKind 79 val constant.Value 80 }{ 81 {"true", UntypedBool, constant.MakeBool(true)}, 82 {"false", UntypedBool, constant.MakeBool(false)}, 83 {"iota", UntypedInt, constant.MakeInt64(0)}, 84 } 85 86 func defPredeclaredConsts() { 87 for _, c := range predeclaredConsts { 88 def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val)) 89 } 90 } 91 92 func defPredeclaredNil() { 93 def(&Nil{object{name: "nil", typ: Typ[UntypedNil]}}) 94 } 95 96 // A builtinId is the id of a builtin function. 97 type builtinId int 98 99 const ( 100 // universe scope 101 _Append builtinId = iota 102 _Cap 103 _Close 104 _Complex 105 _Copy 106 _Delete 107 _Imag 108 _Len 109 _Make 110 _New 111 _Panic 112 _Print 113 _Println 114 _Real 115 _Recover 116 117 // package unsafe 118 _Alignof 119 _Offsetof 120 _Sizeof 121 122 // testing support 123 _Assert 124 _Trace 125 ) 126 127 var predeclaredFuncs = [...]struct { 128 name string 129 nargs int 130 variadic bool 131 kind exprKind 132 }{ 133 _Append: {"append", 1, true, expression}, 134 _Cap: {"cap", 1, false, expression}, 135 _Close: {"close", 1, false, statement}, 136 _Complex: {"complex", 2, false, expression}, 137 _Copy: {"copy", 2, false, statement}, 138 _Delete: {"delete", 2, false, statement}, 139 _Imag: {"imag", 1, false, expression}, 140 _Len: {"len", 1, false, expression}, 141 _Make: {"make", 1, true, expression}, 142 _New: {"new", 1, false, expression}, 143 _Panic: {"panic", 1, false, statement}, 144 _Print: {"print", 0, true, statement}, 145 _Println: {"println", 0, true, statement}, 146 _Real: {"real", 1, false, expression}, 147 _Recover: {"recover", 0, false, statement}, 148 149 _Alignof: {"Alignof", 1, false, expression}, 150 _Offsetof: {"Offsetof", 1, false, expression}, 151 _Sizeof: {"Sizeof", 1, false, expression}, 152 153 _Assert: {"assert", 1, false, statement}, 154 _Trace: {"trace", 0, true, statement}, 155 } 156 157 func defPredeclaredFuncs() { 158 for i := range predeclaredFuncs { 159 id := builtinId(i) 160 if id == _Assert || id == _Trace { 161 continue // only define these in testing environment 162 } 163 def(newBuiltin(id)) 164 } 165 } 166 167 // DefPredeclaredTestFuncs defines the assert and trace built-ins. 168 // These built-ins are intended for debugging and testing of this 169 // package only. 170 func DefPredeclaredTestFuncs() { 171 if Universe.Lookup("assert") != nil { 172 return // already defined 173 } 174 def(newBuiltin(_Assert)) 175 def(newBuiltin(_Trace)) 176 } 177 178 func init() { 179 Universe = NewScope(nil, token.NoPos, token.NoPos, "universe") 180 Unsafe = NewPackage("unsafe", "unsafe") 181 Unsafe.complete = true 182 183 defPredeclaredTypes() 184 defPredeclaredConsts() 185 defPredeclaredNil() 186 defPredeclaredFuncs() 187 188 universeIota = Universe.Lookup("iota").(*Const) 189 universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic) 190 universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic) 191 } 192 193 // Objects with names containing blanks are internal and not entered into 194 // a scope. Objects with exported names are inserted in the unsafe package 195 // scope; other objects are inserted in the universe scope. 196 // 197 func def(obj Object) { 198 name := obj.Name() 199 if strings.Contains(name, " ") { 200 return // nothing to do 201 } 202 // fix Obj link for named types 203 if typ, ok := obj.Type().(*Named); ok { 204 typ.obj = obj.(*TypeName) 205 } 206 // exported identifiers go into package unsafe 207 scope := Universe 208 if obj.Exported() { 209 scope = Unsafe.scope 210 // set Pkg field 211 switch obj := obj.(type) { 212 case *TypeName: 213 obj.pkg = Unsafe 214 case *Builtin: 215 obj.pkg = Unsafe 216 default: 217 unreachable() 218 } 219 } 220 if scope.Insert(obj) != nil { 221 panic("internal error: double declaration") 222 } 223 }