...

Source file src/pkg/go/types/universe.go

     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