...
Run Format

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

View as plain text