...

Source file src/go/types/universe.go

Documentation: go/types

		 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/internal/typeparams"
		12  	"go/token"
		13  	"strings"
		14  )
		15  
		16  // The Universe scope contains all predeclared objects of Go.
		17  // It is the outermost scope of any chain of nested scopes.
		18  var Universe *Scope
		19  
		20  // The Unsafe package is the package returned by an importer
		21  // for the import path "unsafe".
		22  var Unsafe *Package
		23  
		24  var (
		25  	universeIota	*Const
		26  	universeByte	*Basic // uint8 alias, but has name "byte"
		27  	universeRune	*Basic // int32 alias, but has name "rune"
		28  	universeAny	 *Interface
		29  	universeError *Named
		30  )
		31  
		32  // Typ contains the predeclared *Basic types indexed by their
		33  // corresponding BasicKind.
		34  //
		35  // The *Basic type for Typ[Byte] will have the name "uint8".
		36  // Use Universe.Lookup("byte").Type() to obtain the specific
		37  // alias basic type named "byte" (and analogous for "rune").
		38  var Typ = []*Basic{
		39  	Invalid: {Invalid, 0, "invalid type"},
		40  
		41  	Bool:					{Bool, IsBoolean, "bool"},
		42  	Int:					 {Int, IsInteger, "int"},
		43  	Int8:					{Int8, IsInteger, "int8"},
		44  	Int16:				 {Int16, IsInteger, "int16"},
		45  	Int32:				 {Int32, IsInteger, "int32"},
		46  	Int64:				 {Int64, IsInteger, "int64"},
		47  	Uint:					{Uint, IsInteger | IsUnsigned, "uint"},
		48  	Uint8:				 {Uint8, IsInteger | IsUnsigned, "uint8"},
		49  	Uint16:				{Uint16, IsInteger | IsUnsigned, "uint16"},
		50  	Uint32:				{Uint32, IsInteger | IsUnsigned, "uint32"},
		51  	Uint64:				{Uint64, IsInteger | IsUnsigned, "uint64"},
		52  	Uintptr:			 {Uintptr, IsInteger | IsUnsigned, "uintptr"},
		53  	Float32:			 {Float32, IsFloat, "float32"},
		54  	Float64:			 {Float64, IsFloat, "float64"},
		55  	Complex64:		 {Complex64, IsComplex, "complex64"},
		56  	Complex128:		{Complex128, IsComplex, "complex128"},
		57  	String:				{String, IsString, "string"},
		58  	UnsafePointer: {UnsafePointer, 0, "Pointer"},
		59  
		60  	UntypedBool:		{UntypedBool, IsBoolean | IsUntyped, "untyped bool"},
		61  	UntypedInt:		 {UntypedInt, IsInteger | IsUntyped, "untyped int"},
		62  	UntypedRune:		{UntypedRune, IsInteger | IsUntyped, "untyped rune"},
		63  	UntypedFloat:	 {UntypedFloat, IsFloat | IsUntyped, "untyped float"},
		64  	UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"},
		65  	UntypedString:	{UntypedString, IsString | IsUntyped, "untyped string"},
		66  	UntypedNil:		 {UntypedNil, IsUntyped, "untyped nil"},
		67  }
		68  
		69  var aliases = [...]*Basic{
		70  	{Byte, IsInteger | IsUnsigned, "byte"},
		71  	{Rune, IsInteger, "rune"},
		72  }
		73  
		74  func defPredeclaredTypes() {
		75  	for _, t := range Typ {
		76  		def(NewTypeName(token.NoPos, nil, t.name, t))
		77  	}
		78  	for _, t := range aliases {
		79  		def(NewTypeName(token.NoPos, nil, t.name, t))
		80  	}
		81  
		82  	// any
		83  	// (Predeclared and entered into universe scope so we do all the
		84  	// usual checks; but removed again from scope later since it's
		85  	// only visible as constraint in a type parameter list.)
		86  	def(NewTypeName(token.NoPos, nil, "any", &emptyInterface))
		87  
		88  	// Error has a nil package in its qualified name since it is in no package
		89  	{
		90  		res := NewVar(token.NoPos, nil, "", Typ[String])
		91  		sig := &Signature{results: NewTuple(res)}
		92  		err := NewFunc(token.NoPos, nil, "Error", sig)
		93  		typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()}
		94  		sig.recv = NewVar(token.NoPos, nil, "", typ)
		95  		def(NewTypeName(token.NoPos, nil, "error", typ))
		96  	}
		97  }
		98  
		99  var predeclaredConsts = [...]struct {
	 100  	name string
	 101  	kind BasicKind
	 102  	val	constant.Value
	 103  }{
	 104  	{"true", UntypedBool, constant.MakeBool(true)},
	 105  	{"false", UntypedBool, constant.MakeBool(false)},
	 106  	{"iota", UntypedInt, constant.MakeInt64(0)},
	 107  }
	 108  
	 109  func defPredeclaredConsts() {
	 110  	for _, c := range predeclaredConsts {
	 111  		def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val))
	 112  	}
	 113  }
	 114  
	 115  func defPredeclaredNil() {
	 116  	def(&Nil{object{name: "nil", typ: Typ[UntypedNil], color_: black}})
	 117  }
	 118  
	 119  // A builtinId is the id of a builtin function.
	 120  type builtinId int
	 121  
	 122  const (
	 123  	// universe scope
	 124  	_Append builtinId = iota
	 125  	_Cap
	 126  	_Close
	 127  	_Complex
	 128  	_Copy
	 129  	_Delete
	 130  	_Imag
	 131  	_Len
	 132  	_Make
	 133  	_New
	 134  	_Panic
	 135  	_Print
	 136  	_Println
	 137  	_Real
	 138  	_Recover
	 139  
	 140  	// package unsafe
	 141  	_Add
	 142  	_Alignof
	 143  	_Offsetof
	 144  	_Sizeof
	 145  	_Slice
	 146  
	 147  	// testing support
	 148  	_Assert
	 149  	_Trace
	 150  )
	 151  
	 152  var predeclaredFuncs = [...]struct {
	 153  	name		 string
	 154  	nargs		int
	 155  	variadic bool
	 156  	kind		 exprKind
	 157  }{
	 158  	_Append:	{"append", 1, true, expression},
	 159  	_Cap:		 {"cap", 1, false, expression},
	 160  	_Close:	 {"close", 1, false, statement},
	 161  	_Complex: {"complex", 2, false, expression},
	 162  	_Copy:		{"copy", 2, false, statement},
	 163  	_Delete:	{"delete", 2, false, statement},
	 164  	_Imag:		{"imag", 1, false, expression},
	 165  	_Len:		 {"len", 1, false, expression},
	 166  	_Make:		{"make", 1, true, expression},
	 167  	_New:		 {"new", 1, false, expression},
	 168  	_Panic:	 {"panic", 1, false, statement},
	 169  	_Print:	 {"print", 0, true, statement},
	 170  	_Println: {"println", 0, true, statement},
	 171  	_Real:		{"real", 1, false, expression},
	 172  	_Recover: {"recover", 0, false, statement},
	 173  
	 174  	_Add:			{"Add", 2, false, expression},
	 175  	_Alignof:	{"Alignof", 1, false, expression},
	 176  	_Offsetof: {"Offsetof", 1, false, expression},
	 177  	_Sizeof:	 {"Sizeof", 1, false, expression},
	 178  	_Slice:		{"Slice", 2, false, expression},
	 179  
	 180  	_Assert: {"assert", 1, false, statement},
	 181  	_Trace:	{"trace", 0, true, statement},
	 182  }
	 183  
	 184  func defPredeclaredFuncs() {
	 185  	for i := range predeclaredFuncs {
	 186  		id := builtinId(i)
	 187  		if id == _Assert || id == _Trace {
	 188  			continue // only define these in testing environment
	 189  		}
	 190  		def(newBuiltin(id))
	 191  	}
	 192  }
	 193  
	 194  // DefPredeclaredTestFuncs defines the assert and trace built-ins.
	 195  // These built-ins are intended for debugging and testing of this
	 196  // package only.
	 197  func DefPredeclaredTestFuncs() {
	 198  	if Universe.Lookup("assert") != nil {
	 199  		return // already defined
	 200  	}
	 201  	def(newBuiltin(_Assert))
	 202  	def(newBuiltin(_Trace))
	 203  }
	 204  
	 205  func defPredeclaredComparable() {
	 206  	// The "comparable" interface can be imagined as defined like
	 207  	//
	 208  	// type comparable interface {
	 209  	//				 == () untyped bool
	 210  	//				 != () untyped bool
	 211  	// }
	 212  	//
	 213  	// == and != cannot be user-declared but we can declare
	 214  	// a magic method == and check for its presence when needed.
	 215  
	 216  	// Define interface { == () }. We don't care about the signature
	 217  	// for == so leave it empty except for the receiver, which is
	 218  	// set up later to match the usual interface method assumptions.
	 219  	sig := new(Signature)
	 220  	eql := NewFunc(token.NoPos, nil, "==", sig)
	 221  	iface := NewInterfaceType([]*Func{eql}, nil).Complete()
	 222  
	 223  	// set up the defined type for the interface
	 224  	obj := NewTypeName(token.NoPos, nil, "comparable", nil)
	 225  	named := NewNamed(obj, iface, nil)
	 226  	obj.color_ = black
	 227  	sig.recv = NewVar(token.NoPos, nil, "", named) // complete == signature
	 228  
	 229  	def(obj)
	 230  }
	 231  
	 232  func init() {
	 233  	Universe = NewScope(nil, token.NoPos, token.NoPos, "universe")
	 234  	Unsafe = NewPackage("unsafe", "unsafe")
	 235  	Unsafe.complete = true
	 236  
	 237  	defPredeclaredTypes()
	 238  	defPredeclaredConsts()
	 239  	defPredeclaredNil()
	 240  	defPredeclaredFuncs()
	 241  	if typeparams.Enabled {
	 242  		defPredeclaredComparable()
	 243  	}
	 244  
	 245  	universeIota = Universe.Lookup("iota").(*Const)
	 246  	universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
	 247  	universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
	 248  	universeAny = Universe.Lookup("any").(*TypeName).typ.(*Interface)
	 249  	universeError = Universe.Lookup("error").(*TypeName).typ.(*Named)
	 250  
	 251  	// "any" is only visible as constraint in a type parameter list
	 252  	delete(Universe.elems, "any")
	 253  }
	 254  
	 255  // Objects with names containing blanks are internal and not entered into
	 256  // a scope. Objects with exported names are inserted in the unsafe package
	 257  // scope; other objects are inserted in the universe scope.
	 258  //
	 259  func def(obj Object) {
	 260  	assert(obj.color() == black)
	 261  	name := obj.Name()
	 262  	if strings.Contains(name, " ") {
	 263  		return // nothing to do
	 264  	}
	 265  	// fix Obj link for named types
	 266  	if typ := asNamed(obj.Type()); typ != nil {
	 267  		typ.obj = obj.(*TypeName)
	 268  	}
	 269  	// exported identifiers go into package unsafe
	 270  	scope := Universe
	 271  	if obj.Exported() {
	 272  		scope = Unsafe.scope
	 273  		// set Pkg field
	 274  		switch obj := obj.(type) {
	 275  		case *TypeName:
	 276  			obj.pkg = Unsafe
	 277  		case *Builtin:
	 278  			obj.pkg = Unsafe
	 279  		default:
	 280  			unreachable()
	 281  		}
	 282  	}
	 283  	if scope.Insert(obj) != nil {
	 284  		panic("internal error: double declaration")
	 285  	}
	 286  }
	 287  

View as plain text