go.tools/go/importer: handle predeclared types consistently

- pre-poluate typIndex and typList using a predefined list of types
- no need to handle basic types explicitly anymore
- removed basicTag
- go/types: exported UniverseByte and UniverseRune for now

LGTM=adonovan
R=adonovan
CC=cmang, golang-codereviews
https://golang.org/cl/65920044
This commit is contained in:
Robert Griesemer 2014-02-19 13:27:11 -08:00
parent aaa5866ea1
commit 9d6717b260
8 changed files with 95 additions and 67 deletions

View File

@ -21,44 +21,6 @@ const (
trace = false // print emitted data
)
const (
magic = "\n$$ exports $$\n"
version = "v0"
)
// Tags. Must be < 0.
const (
// Packages
packageTag = -(iota + 1)
// Objects
constTag
typeTag
varTag
funcTag
// Types
basicTag
arrayTag
sliceTag
structTag
pointerTag
signatureTag
interfaceTag
mapTag
chanTag
namedTag
// Values
int64Tag
floatTag
fractionTag
complexTag
stringTag
falseTag
trueTag
)
// ExportData serializes the interface (exported package objects)
// of package pkg and returns the corresponding data. The export
// format is described elsewhere (TODO).
@ -70,10 +32,9 @@ func ExportData(pkg *types.Package) []byte {
}
// populate typIndex with predeclared types
for _, t := range types.Typ[1:] {
for _, t := range predeclared {
p.typIndex[t] = len(p.typIndex)
}
p.typIndex[types.Universe.Lookup("error").Type()] = len(p.typIndex)
if trace {
p.tracef("export %s\n", pkg.Name())
@ -253,16 +214,6 @@ func (p *exporter) typ(typ types.Type) {
// otherwise, write the type tag (< 0) and type data
switch t := typ.(type) {
case *types.Basic:
// Basic types are pre-recorded and don't usually end up here.
// However, the alias types byte and rune are not in the types.Typ
// table and get emitted here (once per package, if they appear).
// This permits faithful reconstruction of the alias type (i.e.,
// keeping the name). If we decide to eliminate the distinction
// between the alias types, this code can go.
p.int(basicTag)
p.string(t.Name())
case *types.Array:
p.int(arrayTag)
p.int64(t.Len())

View File

@ -35,10 +35,9 @@ func ImportData(imports map[string]*types.Package, data []byte) (*types.Package,
}
// populate typList with predeclared types
for _, t := range types.Typ[1:] {
for _, t := range predeclared {
p.typList = append(p.typList, t)
}
p.typList = append(p.typList, types.Universe.Lookup("error").Type())
if v := p.string(); v != version {
return nil, fmt.Errorf("unknown version: got %s; want %s", v, version)
@ -199,11 +198,6 @@ func (p *importer) typ() types.Type {
// otherwise, i is the type tag (< 0)
switch i {
case basicTag:
t := types.Universe.Lookup(p.string()).(*types.TypeName).Type().(*types.Basic)
p.record(t)
return t
case arrayTag:
t := new(types.Array)
p.record(t)

83
go/importer/predefined.go Normal file
View File

@ -0,0 +1,83 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package importer
import "code.google.com/p/go.tools/go/types"
const (
magic = "\n$$ exports $$\n"
version = "v0"
)
// Tags. Must be < 0.
const (
// Packages
packageTag = -(iota + 1)
// Objects
constTag
typeTag
varTag
funcTag
// Types
arrayTag
sliceTag
structTag
pointerTag
signatureTag
interfaceTag
mapTag
chanTag
namedTag
// Values
falseTag
trueTag
int64Tag
floatTag
fractionTag
complexTag
stringTag
)
var predeclared = []types.Type{
// basic types
types.Typ[types.Bool],
types.Typ[types.Int],
types.Typ[types.Int8],
types.Typ[types.Int16],
types.Typ[types.Int32],
types.Typ[types.Int64],
types.Typ[types.Uint],
types.Typ[types.Uint8],
types.Typ[types.Uint16],
types.Typ[types.Uint32],
types.Typ[types.Uint64],
types.Typ[types.Uintptr],
types.Typ[types.Float32],
types.Typ[types.Float64],
types.Typ[types.Complex64],
types.Typ[types.Complex128],
types.Typ[types.String],
// untyped types
types.Typ[types.UntypedBool],
types.Typ[types.UntypedInt],
types.Typ[types.UntypedRune],
types.Typ[types.UntypedFloat],
types.Typ[types.UntypedComplex],
types.Typ[types.UntypedString],
types.Typ[types.UntypedNil],
// package unsafe
types.Typ[types.UnsafePointer],
// aliases
types.UniverseByte,
types.UniverseRune,
types.Universe.Lookup("error").Type(),
}

View File

@ -81,14 +81,14 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// spec: "As a special case, append also accepts a first argument assignable
// to type []byte with a second argument of string type followed by ... .
// This form appends the bytes of the string.
if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(universeByte)) {
if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(UniverseByte)) {
arg(x, 1)
if x.mode == invalid {
return
}
if isString(x.typ) {
if check.Types != nil {
sig := makeSig(S, S, NewSlice(universeByte))
sig := makeSig(S, S, NewSlice(UniverseByte))
sig.variadic = true
check.recordBuiltinType(call.Fun, sig)
}
@ -274,7 +274,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
switch t := y.typ.Underlying().(type) {
case *Basic:
if isString(y.typ) {
src = universeByte
src = UniverseByte
}
case *Slice:
src = t.elem

View File

@ -1141,7 +1141,7 @@ func (check *checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
// (not a constant) even if the string and the
// index are constant
x.mode = value
x.typ = universeByte // use 'byte' name
x.typ = UniverseByte // use 'byte' name
}
case *Array:

View File

@ -295,7 +295,7 @@ func defaultType(typ Type) Type {
case UntypedInt:
return Typ[Int]
case UntypedRune:
return universeRune // use 'rune' name
return UniverseRune // use 'rune' name
case UntypedFloat:
return Typ[Float64]
case UntypedComplex:

View File

@ -609,7 +609,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
case *Basic:
if isString(typ) {
key = Typ[Int]
val = universeRune // use 'rune' name
val = UniverseRune // use 'rune' name
}
case *Array:
key = Typ[Int]

View File

@ -17,8 +17,8 @@ var (
Universe *Scope
Unsafe *Package
universeIota *Const
universeByte *Basic
universeRune *Basic
UniverseByte *Basic // uint8 alias, but has name "byte"
UniverseRune *Basic // int32 alias, but has name "rune"
)
var Typ = [...]*Basic{
@ -187,8 +187,8 @@ func init() {
defPredeclaredFuncs()
universeIota = Universe.Lookup("iota").(*Const)
universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
UniverseByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
UniverseRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
}
// Objects with names containing blanks are internal and not entered into