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:
parent
aaa5866ea1
commit
9d6717b260
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue