github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gotools/go/importer/export.go (about) 1 // Copyright 2013 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 package importer 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "fmt" 11 "go/ast" 12 "strings" 13 14 "llvm.org/llgo/third_party/gotools/go/exact" 15 "llvm.org/llgo/third_party/gotools/go/types" 16 ) 17 18 // debugging support 19 const ( 20 debug = false // emit debugging data 21 trace = false // print emitted data 22 ) 23 24 // format returns a byte indicating the low-level encoding/decoding format 25 // (debug vs product). 26 func format() byte { 27 if debug { 28 return 'd' 29 } 30 return 'p' 31 } 32 33 // ExportData serializes the interface (exported package objects) 34 // of package pkg and returns the corresponding data. The export 35 // format is described elsewhere (TODO). 36 func ExportData(pkg *types.Package) []byte { 37 p := exporter{ 38 data: append([]byte(magic), format()), 39 pkgIndex: make(map[*types.Package]int), 40 typIndex: make(map[types.Type]int), 41 } 42 43 // populate typIndex with predeclared types 44 for _, t := range predeclared { 45 p.typIndex[t] = len(p.typIndex) 46 } 47 48 if trace { 49 p.tracef("export %s\n", pkg.Name()) 50 defer p.tracef("\n") 51 } 52 53 p.string(version) 54 55 p.pkg(pkg) 56 57 // collect exported objects from package scope 58 var list []types.Object 59 scope := pkg.Scope() 60 for _, name := range scope.Names() { 61 if exported(name) { 62 list = append(list, scope.Lookup(name)) 63 } 64 } 65 66 // write objects 67 p.int(len(list)) 68 for _, obj := range list { 69 p.obj(obj) 70 } 71 72 return p.data 73 } 74 75 type exporter struct { 76 data []byte 77 pkgIndex map[*types.Package]int 78 typIndex map[types.Type]int 79 80 // tracing support 81 indent string 82 } 83 84 func (p *exporter) pkg(pkg *types.Package) { 85 if trace { 86 p.tracef("package { ") 87 defer p.tracef("} ") 88 } 89 90 if pkg == nil { 91 panic("unexpected nil pkg") 92 } 93 94 // if the package was seen before, write its index (>= 0) 95 if i, ok := p.pkgIndex[pkg]; ok { 96 p.int(i) 97 return 98 } 99 p.pkgIndex[pkg] = len(p.pkgIndex) 100 101 // otherwise, write the package tag (< 0) and package data 102 p.int(packageTag) 103 p.string(pkg.Name()) 104 p.string(pkg.Path()) 105 } 106 107 func (p *exporter) obj(obj types.Object) { 108 if trace { 109 p.tracef("object %s {\n", obj.Name()) 110 defer p.tracef("}\n") 111 } 112 113 switch obj := obj.(type) { 114 case *types.Const: 115 p.int(constTag) 116 p.string(obj.Name()) 117 p.typ(obj.Type()) 118 p.value(obj.Val()) 119 case *types.TypeName: 120 p.int(typeTag) 121 // name is written by corresponding named type 122 p.typ(obj.Type().(*types.Named)) 123 case *types.Var: 124 p.int(varTag) 125 p.string(obj.Name()) 126 p.typ(obj.Type()) 127 case *types.Func: 128 p.int(funcTag) 129 p.string(obj.Name()) 130 p.typ(obj.Type()) 131 default: 132 panic(fmt.Sprintf("unexpected object type %T", obj)) 133 } 134 } 135 136 func (p *exporter) value(x exact.Value) { 137 if trace { 138 p.tracef("value { ") 139 defer p.tracef("} ") 140 } 141 142 switch kind := x.Kind(); kind { 143 case exact.Bool: 144 tag := falseTag 145 if exact.BoolVal(x) { 146 tag = trueTag 147 } 148 p.int(tag) 149 case exact.Int: 150 if i, ok := exact.Int64Val(x); ok { 151 p.int(int64Tag) 152 p.int64(i) 153 return 154 } 155 p.int(floatTag) 156 p.float(x) 157 case exact.Float: 158 p.int(fractionTag) 159 p.fraction(x) 160 case exact.Complex: 161 p.int(complexTag) 162 p.fraction(exact.Real(x)) 163 p.fraction(exact.Imag(x)) 164 case exact.String: 165 p.int(stringTag) 166 p.string(exact.StringVal(x)) 167 default: 168 panic(fmt.Sprintf("unexpected value kind %d", kind)) 169 } 170 } 171 172 func (p *exporter) float(x exact.Value) { 173 sign := exact.Sign(x) 174 p.int(sign) 175 if sign == 0 { 176 return 177 } 178 179 p.ufloat(x) 180 } 181 182 func (p *exporter) fraction(x exact.Value) { 183 sign := exact.Sign(x) 184 p.int(sign) 185 if sign == 0 { 186 return 187 } 188 189 p.ufloat(exact.Num(x)) 190 p.ufloat(exact.Denom(x)) 191 } 192 193 // ufloat writes abs(x) in form of a binary exponent 194 // followed by its mantissa bytes; x must be != 0. 195 func (p *exporter) ufloat(x exact.Value) { 196 mant := exact.Bytes(x) 197 exp8 := -1 198 for i, b := range mant { 199 if b != 0 { 200 exp8 = i 201 break 202 } 203 } 204 if exp8 < 0 { 205 panic(fmt.Sprintf("%s has no mantissa", x)) 206 } 207 p.int(exp8 * 8) 208 p.bytes(mant[exp8:]) 209 } 210 211 func (p *exporter) typ(typ types.Type) { 212 if trace { 213 p.tracef("type {\n") 214 defer p.tracef("}\n") 215 } 216 217 // if the type was seen before, write its index (>= 0) 218 if i, ok := p.typIndex[typ]; ok { 219 p.int(i) 220 return 221 } 222 p.typIndex[typ] = len(p.typIndex) 223 224 // otherwise, write the type tag (< 0) and type data 225 switch t := typ.(type) { 226 case *types.Array: 227 p.int(arrayTag) 228 p.int64(t.Len()) 229 p.typ(t.Elem()) 230 231 case *types.Slice: 232 p.int(sliceTag) 233 p.typ(t.Elem()) 234 235 case *types.Struct: 236 p.int(structTag) 237 n := t.NumFields() 238 p.int(n) 239 for i := 0; i < n; i++ { 240 p.field(t.Field(i)) 241 p.string(t.Tag(i)) 242 } 243 244 case *types.Pointer: 245 p.int(pointerTag) 246 p.typ(t.Elem()) 247 248 case *types.Signature: 249 p.int(signatureTag) 250 p.signature(t) 251 252 case *types.Interface: 253 p.int(interfaceTag) 254 255 // write embedded interfaces 256 m := t.NumEmbeddeds() 257 p.int(m) 258 for i := 0; i < m; i++ { 259 p.typ(t.Embedded(i)) 260 } 261 262 // write methods 263 n := t.NumExplicitMethods() 264 p.int(n) 265 for i := 0; i < n; i++ { 266 m := t.ExplicitMethod(i) 267 p.qualifiedName(m.Pkg(), m.Name()) 268 p.typ(m.Type()) 269 } 270 271 case *types.Map: 272 p.int(mapTag) 273 p.typ(t.Key()) 274 p.typ(t.Elem()) 275 276 case *types.Chan: 277 p.int(chanTag) 278 p.int(int(t.Dir())) 279 p.typ(t.Elem()) 280 281 case *types.Named: 282 p.int(namedTag) 283 284 // write type object 285 obj := t.Obj() 286 p.string(obj.Name()) 287 p.pkg(obj.Pkg()) 288 289 // write underlying type 290 p.typ(t.Underlying()) 291 292 // write associated methods 293 n := t.NumMethods() 294 p.int(n) 295 for i := 0; i < n; i++ { 296 m := t.Method(i) 297 p.string(m.Name()) 298 p.typ(m.Type()) 299 } 300 301 default: 302 panic("unreachable") 303 } 304 } 305 306 func (p *exporter) field(f *types.Var) { 307 // anonymous fields have "" name 308 name := "" 309 if !f.Anonymous() { 310 name = f.Name() 311 } 312 313 // qualifiedName will always emit the field package for 314 // anonymous fields because "" is not an exported name. 315 p.qualifiedName(f.Pkg(), name) 316 p.typ(f.Type()) 317 } 318 319 func (p *exporter) qualifiedName(pkg *types.Package, name string) { 320 p.string(name) 321 // exported names don't need package 322 if !exported(name) { 323 if pkg == nil { 324 panic(fmt.Sprintf("nil package for unexported qualified name %s", name)) 325 } 326 p.pkg(pkg) 327 } 328 } 329 330 func (p *exporter) signature(sig *types.Signature) { 331 // We need the receiver information (T vs *T) 332 // for methods associated with named types. 333 // We do not record interface receiver types in the 334 // export data because 1) the importer can derive them 335 // from the interface type and 2) they create cycles 336 // in the type graph. 337 if recv := sig.Recv(); recv != nil { 338 if _, ok := recv.Type().Underlying().(*types.Interface); !ok { 339 // 1-element tuple 340 p.int(1) 341 p.param(recv) 342 } else { 343 // 0-element tuple 344 p.int(0) 345 } 346 } else { 347 // 0-element tuple 348 p.int(0) 349 } 350 p.tuple(sig.Params()) 351 p.tuple(sig.Results()) 352 if sig.Variadic() { 353 p.int(1) 354 } else { 355 p.int(0) 356 } 357 } 358 359 func (p *exporter) param(v *types.Var) { 360 p.string(v.Name()) 361 p.typ(v.Type()) 362 } 363 364 func (p *exporter) tuple(t *types.Tuple) { 365 n := t.Len() 366 p.int(n) 367 for i := 0; i < n; i++ { 368 p.param(t.At(i)) 369 } 370 } 371 372 // ---------------------------------------------------------------------------- 373 // encoders 374 375 func (p *exporter) string(s string) { 376 p.bytes([]byte(s)) // (could be inlined if extra allocation matters) 377 } 378 379 func (p *exporter) int(x int) { 380 p.int64(int64(x)) 381 } 382 383 func (p *exporter) int64(x int64) { 384 if debug { 385 p.marker('i') 386 } 387 388 if trace { 389 p.tracef("%d ", x) 390 } 391 392 p.rawInt64(x) 393 } 394 395 func (p *exporter) bytes(b []byte) { 396 if debug { 397 p.marker('b') 398 } 399 400 if trace { 401 p.tracef("%q ", b) 402 } 403 404 p.rawInt64(int64(len(b))) 405 if len(b) > 0 { 406 p.data = append(p.data, b...) 407 } 408 } 409 410 // marker emits a marker byte and position information which makes 411 // it easy for a reader to detect if it is "out of sync". Used for 412 // debug format only. 413 func (p *exporter) marker(m byte) { 414 if debug { 415 p.data = append(p.data, m) 416 p.rawInt64(int64(len(p.data))) 417 } 418 } 419 420 // rawInt64 should only be used by low-level encoders 421 func (p *exporter) rawInt64(x int64) { 422 var tmp [binary.MaxVarintLen64]byte 423 n := binary.PutVarint(tmp[:], x) 424 p.data = append(p.data, tmp[:n]...) 425 } 426 427 // utility functions 428 429 func (p *exporter) tracef(format string, args ...interface{}) { 430 // rewrite format string to take care of indentation 431 const indent = ". " 432 if strings.IndexAny(format, "{}\n") >= 0 { 433 var buf bytes.Buffer 434 for i := 0; i < len(format); i++ { 435 // no need to deal with runes 436 ch := format[i] 437 switch ch { 438 case '{': 439 p.indent += indent 440 case '}': 441 p.indent = p.indent[:len(p.indent)-len(indent)] 442 if i+1 < len(format) && format[i+1] == '\n' { 443 buf.WriteByte('\n') 444 buf.WriteString(p.indent) 445 buf.WriteString("} ") 446 i++ 447 continue 448 } 449 } 450 buf.WriteByte(ch) 451 if ch == '\n' { 452 buf.WriteString(p.indent) 453 } 454 } 455 format = buf.String() 456 } 457 fmt.Printf(format, args...) 458 } 459 460 func exported(name string) bool { 461 return ast.IsExported(name) 462 }