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 is a copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go,
6// but it also contains the original source-based importer code for Go1.6.
7// Once we stop supporting 1.6, we can remove that code.
8
9// Package gcimporter15 provides various functions for reading
10// gc-generated object files that can be used to implement the
11// Importer interface defined by the Go 1.5 standard library package.
12//
13// Deprecated: this package will be deleted in October 2017.
14// New code should use golang.org/x/tools/go/gcexportdata.
15//
16package gcimporter // import "golang.org/x/tools/go/gcimporter15"
17
18import (
19	"bufio"
20	"errors"
21	"fmt"
22	"go/build"
23	exact "go/constant"
24	"go/token"
25	"go/types"
26	"io"
27	"io/ioutil"
28	"os"
29	"path/filepath"
30	"sort"
31	"strconv"
32	"strings"
33	"text/scanner"
34)
35
36// debugging/development support
37const debug = false
38
39var pkgExts = [...]string{".a", ".o"}
40
41// FindPkg returns the filename and unique package id for an import
42// path based on package information provided by build.Import (using
43// the build.Default build.Context). A relative srcDir is interpreted
44// relative to the current working directory.
45// If no file was found, an empty filename is returned.
46//
47func FindPkg(path, srcDir string) (filename, id string) {
48	if path == "" {
49		return
50	}
51
52	var noext string
53	switch {
54	default:
55		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
56		// Don't require the source files to be present.
57		if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
58			srcDir = abs
59		}
60		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
61		if bp.PkgObj == "" {
62			return
63		}
64		noext = strings.TrimSuffix(bp.PkgObj, ".a")
65		id = bp.ImportPath
66
67	case build.IsLocalImport(path):
68		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
69		noext = filepath.Join(srcDir, path)
70		id = noext
71
72	case filepath.IsAbs(path):
73		// for completeness only - go/build.Import
74		// does not support absolute imports
75		// "/x" -> "/x.ext", "/x"
76		noext = path
77		id = path
78	}
79
80	if false { // for debugging
81		if path != id {
82			fmt.Printf("%s -> %s\n", path, id)
83		}
84	}
85
86	// try extensions
87	for _, ext := range pkgExts {
88		filename = noext + ext
89		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
90			return
91		}
92	}
93
94	filename = "" // not found
95	return
96}
97
98// ImportData imports a package by reading the gc-generated export data,
99// adds the corresponding package object to the packages map indexed by id,
100// and returns the object.
101//
102// The packages map must contains all packages already imported. The data
103// reader position must be the beginning of the export data section. The
104// filename is only used in error messages.
105//
106// If packages[id] contains the completely imported package, that package
107// can be used directly, and there is no need to call this function (but
108// there is also no harm but for extra time used).
109//
110func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
111	// support for parser error handling
112	defer func() {
113		switch r := recover().(type) {
114		case nil:
115			// nothing to do
116		case importError:
117			err = r
118		default:
119			panic(r) // internal error
120		}
121	}()
122
123	var p parser
124	p.init(filename, id, data, packages)
125	pkg = p.parseExport()
126
127	return
128}
129
130// Import imports a gc-generated package given its import path and srcDir, adds
131// the corresponding package object to the packages map, and returns the object.
132// The packages map must contain all packages already imported.
133//
134func Import(packages map[string]*types.Package, path, srcDir string) (pkg *types.Package, err error) {
135	filename, id := FindPkg(path, srcDir)
136	if filename == "" {
137		if path == "unsafe" {
138			return types.Unsafe, nil
139		}
140		err = fmt.Errorf("can't find import: %s", id)
141		return
142	}
143
144	// no need to re-import if the package was imported completely before
145	if pkg = packages[id]; pkg != nil && pkg.Complete() {
146		return
147	}
148
149	// open file
150	f, err := os.Open(filename)
151	if err != nil {
152		return
153	}
154	defer func() {
155		f.Close()
156		if err != nil {
157			// add file name to error
158			err = fmt.Errorf("reading export data: %s: %v", filename, err)
159		}
160	}()
161
162	var hdr string
163	buf := bufio.NewReader(f)
164	if hdr, err = FindExportData(buf); err != nil {
165		return
166	}
167
168	switch hdr {
169	case "$$\n":
170		return ImportData(packages, filename, id, buf)
171	case "$$B\n":
172		var data []byte
173		data, err = ioutil.ReadAll(buf)
174		if err == nil {
175			fset := token.NewFileSet()
176			_, pkg, err = BImportData(fset, packages, data, id)
177			return
178		}
179	default:
180		err = fmt.Errorf("unknown export data header: %q", hdr)
181	}
182
183	return
184}
185
186// ----------------------------------------------------------------------------
187// Parser
188
189// TODO(gri) Imported objects don't have position information.
190//           Ideally use the debug table line info; alternatively
191//           create some fake position (or the position of the
192//           import). That way error messages referring to imported
193//           objects can print meaningful information.
194
195// parser parses the exports inside a gc compiler-produced
196// object/archive file and populates its scope with the results.
197type parser struct {
198	scanner    scanner.Scanner
199	tok        rune                      // current token
200	lit        string                    // literal string; only valid for Ident, Int, String tokens
201	id         string                    // package id of imported package
202	sharedPkgs map[string]*types.Package // package id -> package object (across importer)
203	localPkgs  map[string]*types.Package // package id -> package object (just this package)
204}
205
206func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) {
207	p.scanner.Init(src)
208	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
209	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
210	p.scanner.Whitespace = 1<<'\t' | 1<<' '
211	p.scanner.Filename = filename // for good error messages
212	p.next()
213	p.id = id
214	p.sharedPkgs = packages
215	if debug {
216		// check consistency of packages map
217		for _, pkg := range packages {
218			if pkg.Name() == "" {
219				fmt.Printf("no package name for %s\n", pkg.Path())
220			}
221		}
222	}
223}
224
225func (p *parser) next() {
226	p.tok = p.scanner.Scan()
227	switch p.tok {
228	case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·':
229		p.lit = p.scanner.TokenText()
230	default:
231		p.lit = ""
232	}
233	if debug {
234		fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
235	}
236}
237
238func declTypeName(pkg *types.Package, name string) *types.TypeName {
239	scope := pkg.Scope()
240	if obj := scope.Lookup(name); obj != nil {
241		return obj.(*types.TypeName)
242	}
243	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
244	// a named type may be referred to before the underlying type
245	// is known - set it up
246	types.NewNamed(obj, nil, nil)
247	scope.Insert(obj)
248	return obj
249}
250
251// ----------------------------------------------------------------------------
252// Error handling
253
254// Internal errors are boxed as importErrors.
255type importError struct {
256	pos scanner.Position
257	err error
258}
259
260func (e importError) Error() string {
261	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
262}
263
264func (p *parser) error(err interface{}) {
265	if s, ok := err.(string); ok {
266		err = errors.New(s)
267	}
268	// panic with a runtime.Error if err is not an error
269	panic(importError{p.scanner.Pos(), err.(error)})
270}
271
272func (p *parser) errorf(format string, args ...interface{}) {
273	p.error(fmt.Sprintf(format, args...))
274}
275
276func (p *parser) expect(tok rune) string {
277	lit := p.lit
278	if p.tok != tok {
279		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
280	}
281	p.next()
282	return lit
283}
284
285func (p *parser) expectSpecial(tok string) {
286	sep := 'x' // not white space
287	i := 0
288	for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
289		sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
290		p.next()
291		i++
292	}
293	if i < len(tok) {
294		p.errorf("expected %q, got %q", tok, tok[0:i])
295	}
296}
297
298func (p *parser) expectKeyword(keyword string) {
299	lit := p.expect(scanner.Ident)
300	if lit != keyword {
301		p.errorf("expected keyword %s, got %q", keyword, lit)
302	}
303}
304
305// ----------------------------------------------------------------------------
306// Qualified and unqualified names
307
308// PackageId = string_lit .
309//
310func (p *parser) parsePackageId() string {
311	id, err := strconv.Unquote(p.expect(scanner.String))
312	if err != nil {
313		p.error(err)
314	}
315	// id == "" stands for the imported package id
316	// (only known at time of package installation)
317	if id == "" {
318		id = p.id
319	}
320	return id
321}
322
323// PackageName = ident .
324//
325func (p *parser) parsePackageName() string {
326	return p.expect(scanner.Ident)
327}
328
329// dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
330func (p *parser) parseDotIdent() string {
331	ident := ""
332	if p.tok != scanner.Int {
333		sep := 'x' // not white space
334		for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
335			ident += p.lit
336			sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
337			p.next()
338		}
339	}
340	if ident == "" {
341		p.expect(scanner.Ident) // use expect() for error handling
342	}
343	return ident
344}
345
346// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) .
347//
348func (p *parser) parseQualifiedName() (id, name string) {
349	p.expect('@')
350	id = p.parsePackageId()
351	p.expect('.')
352	// Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields.
353	if p.tok == '?' {
354		p.next()
355	} else {
356		name = p.parseDotIdent()
357	}
358	return
359}
360
361// getPkg returns the package for a given id. If the package is
362// not found, create the package and add it to the p.localPkgs
363// and p.sharedPkgs maps. name is the (expected) name of the
364// package. If name == "", the package name is expected to be
365// set later via an import clause in the export data.
366//
367// id identifies a package, usually by a canonical package path like
368// "encoding/json" but possibly by a non-canonical import path like
369// "./json".
370//
371func (p *parser) getPkg(id, name string) *types.Package {
372	// package unsafe is not in the packages maps - handle explicitly
373	if id == "unsafe" {
374		return types.Unsafe
375	}
376
377	pkg := p.localPkgs[id]
378	if pkg == nil {
379		// first import of id from this package
380		pkg = p.sharedPkgs[id]
381		if pkg == nil {
382			// first import of id by this importer;
383			// add (possibly unnamed) pkg to shared packages
384			pkg = types.NewPackage(id, name)
385			p.sharedPkgs[id] = pkg
386		}
387		// add (possibly unnamed) pkg to local packages
388		if p.localPkgs == nil {
389			p.localPkgs = make(map[string]*types.Package)
390		}
391		p.localPkgs[id] = pkg
392	} else if name != "" {
393		// package exists already and we have an expected package name;
394		// make sure names match or set package name if necessary
395		if pname := pkg.Name(); pname == "" {
396			pkg.SetName(name)
397		} else if pname != name {
398			p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name)
399		}
400	}
401	return pkg
402}
403
404// parseExportedName is like parseQualifiedName, but
405// the package id is resolved to an imported *types.Package.
406//
407func (p *parser) parseExportedName() (pkg *types.Package, name string) {
408	id, name := p.parseQualifiedName()
409	pkg = p.getPkg(id, "")
410	return
411}
412
413// ----------------------------------------------------------------------------
414// Types
415
416// BasicType = identifier .
417//
418func (p *parser) parseBasicType() types.Type {
419	id := p.expect(scanner.Ident)
420	obj := types.Universe.Lookup(id)
421	if obj, ok := obj.(*types.TypeName); ok {
422		return obj.Type()
423	}
424	p.errorf("not a basic type: %s", id)
425	return nil
426}
427
428// ArrayType = "[" int_lit "]" Type .
429//
430func (p *parser) parseArrayType(parent *types.Package) types.Type {
431	// "[" already consumed and lookahead known not to be "]"
432	lit := p.expect(scanner.Int)
433	p.expect(']')
434	elem := p.parseType(parent)
435	n, err := strconv.ParseInt(lit, 10, 64)
436	if err != nil {
437		p.error(err)
438	}
439	return types.NewArray(elem, n)
440}
441
442// MapType = "map" "[" Type "]" Type .
443//
444func (p *parser) parseMapType(parent *types.Package) types.Type {
445	p.expectKeyword("map")
446	p.expect('[')
447	key := p.parseType(parent)
448	p.expect(']')
449	elem := p.parseType(parent)
450	return types.NewMap(key, elem)
451}
452
453// Name = identifier | "?" | QualifiedName .
454//
455// For unqualified and anonymous names, the returned package is the parent
456// package unless parent == nil, in which case the returned package is the
457// package being imported. (The parent package is not nil if the the name
458// is an unqualified struct field or interface method name belonging to a
459// type declared in another package.)
460//
461// For qualified names, the returned package is nil (and not created if
462// it doesn't exist yet) unless materializePkg is set (which creates an
463// unnamed package with valid package path). In the latter case, a
464// subsequent import clause is expected to provide a name for the package.
465//
466func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) {
467	pkg = parent
468	if pkg == nil {
469		pkg = p.sharedPkgs[p.id]
470	}
471	switch p.tok {
472	case scanner.Ident:
473		name = p.lit
474		p.next()
475	case '?':
476		// anonymous
477		p.next()
478	case '@':
479		// exported name prefixed with package path
480		pkg = nil
481		var id string
482		id, name = p.parseQualifiedName()
483		if materializePkg {
484			pkg = p.getPkg(id, "")
485		}
486	default:
487		p.error("name expected")
488	}
489	return
490}
491
492func deref(typ types.Type) types.Type {
493	if p, _ := typ.(*types.Pointer); p != nil {
494		return p.Elem()
495	}
496	return typ
497}
498
499// Field = Name Type [ string_lit ] .
500//
501func (p *parser) parseField(parent *types.Package) (*types.Var, string) {
502	pkg, name := p.parseName(parent, true)
503
504	if name == "_" {
505		// Blank fields should be package-qualified because they
506		// are unexported identifiers, but gc does not qualify them.
507		// Assuming that the ident belongs to the current package
508		// causes types to change during re-exporting, leading
509		// to spurious "can't assign A to B" errors from go/types.
510		// As a workaround, pretend all blank fields belong
511		// to the same unique dummy package.
512		const blankpkg = "<_>"
513		pkg = p.getPkg(blankpkg, blankpkg)
514	}
515
516	typ := p.parseType(parent)
517	anonymous := false
518	if name == "" {
519		// anonymous field - typ must be T or *T and T must be a type name
520		switch typ := deref(typ).(type) {
521		case *types.Basic: // basic types are named types
522			pkg = nil // objects defined in Universe scope have no package
523			name = typ.Name()
524		case *types.Named:
525			name = typ.Obj().Name()
526		default:
527			p.errorf("anonymous field expected")
528		}
529		anonymous = true
530	}
531	tag := ""
532	if p.tok == scanner.String {
533		s := p.expect(scanner.String)
534		var err error
535		tag, err = strconv.Unquote(s)
536		if err != nil {
537			p.errorf("invalid struct tag %s: %s", s, err)
538		}
539	}
540	return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag
541}
542
543// StructType = "struct" "{" [ FieldList ] "}" .
544// FieldList  = Field { ";" Field } .
545//
546func (p *parser) parseStructType(parent *types.Package) types.Type {
547	var fields []*types.Var
548	var tags []string
549
550	p.expectKeyword("struct")
551	p.expect('{')
552	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
553		if i > 0 {
554			p.expect(';')
555		}
556		fld, tag := p.parseField(parent)
557		if tag != "" && tags == nil {
558			tags = make([]string, i)
559		}
560		if tags != nil {
561			tags = append(tags, tag)
562		}
563		fields = append(fields, fld)
564	}
565	p.expect('}')
566
567	return types.NewStruct(fields, tags)
568}
569
570// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
571//
572func (p *parser) parseParameter() (par *types.Var, isVariadic bool) {
573	_, name := p.parseName(nil, false)
574	// remove gc-specific parameter numbering
575	if i := strings.Index(name, "·"); i >= 0 {
576		name = name[:i]
577	}
578	if p.tok == '.' {
579		p.expectSpecial("...")
580		isVariadic = true
581	}
582	typ := p.parseType(nil)
583	if isVariadic {
584		typ = types.NewSlice(typ)
585	}
586	// ignore argument tag (e.g. "noescape")
587	if p.tok == scanner.String {
588		p.next()
589	}
590	// TODO(gri) should we provide a package?
591	par = types.NewVar(token.NoPos, nil, name, typ)
592	return
593}
594
595// Parameters    = "(" [ ParameterList ] ")" .
596// ParameterList = { Parameter "," } Parameter .
597//
598func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) {
599	p.expect('(')
600	for p.tok != ')' && p.tok != scanner.EOF {
601		if len(list) > 0 {
602			p.expect(',')
603		}
604		par, variadic := p.parseParameter()
605		list = append(list, par)
606		if variadic {
607			if isVariadic {
608				p.error("... not on final argument")
609			}
610			isVariadic = true
611		}
612	}
613	p.expect(')')
614
615	return
616}
617
618// Signature = Parameters [ Result ] .
619// Result    = Type | Parameters .
620//
621func (p *parser) parseSignature(recv *types.Var) *types.Signature {
622	params, isVariadic := p.parseParameters()
623
624	// optional result type
625	var results []*types.Var
626	if p.tok == '(' {
627		var variadic bool
628		results, variadic = p.parseParameters()
629		if variadic {
630			p.error("... not permitted on result type")
631		}
632	}
633
634	return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic)
635}
636
637// InterfaceType = "interface" "{" [ MethodList ] "}" .
638// MethodList    = Method { ";" Method } .
639// Method        = Name Signature .
640//
641// The methods of embedded interfaces are always "inlined"
642// by the compiler and thus embedded interfaces are never
643// visible in the export data.
644//
645func (p *parser) parseInterfaceType(parent *types.Package) types.Type {
646	var methods []*types.Func
647
648	p.expectKeyword("interface")
649	p.expect('{')
650	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
651		if i > 0 {
652			p.expect(';')
653		}
654		pkg, name := p.parseName(parent, true)
655		sig := p.parseSignature(nil)
656		methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig))
657	}
658	p.expect('}')
659
660	// Complete requires the type's embedded interfaces to be fully defined,
661	// but we do not define any
662	return types.NewInterface(methods, nil).Complete()
663}
664
665// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
666//
667func (p *parser) parseChanType(parent *types.Package) types.Type {
668	dir := types.SendRecv
669	if p.tok == scanner.Ident {
670		p.expectKeyword("chan")
671		if p.tok == '<' {
672			p.expectSpecial("<-")
673			dir = types.SendOnly
674		}
675	} else {
676		p.expectSpecial("<-")
677		p.expectKeyword("chan")
678		dir = types.RecvOnly
679	}
680	elem := p.parseType(parent)
681	return types.NewChan(dir, elem)
682}
683
684// Type =
685//	BasicType | TypeName | ArrayType | SliceType | StructType |
686//      PointerType | FuncType | InterfaceType | MapType | ChanType |
687//      "(" Type ")" .
688//
689// BasicType   = ident .
690// TypeName    = ExportedName .
691// SliceType   = "[" "]" Type .
692// PointerType = "*" Type .
693// FuncType    = "func" Signature .
694//
695func (p *parser) parseType(parent *types.Package) types.Type {
696	switch p.tok {
697	case scanner.Ident:
698		switch p.lit {
699		default:
700			return p.parseBasicType()
701		case "struct":
702			return p.parseStructType(parent)
703		case "func":
704			// FuncType
705			p.next()
706			return p.parseSignature(nil)
707		case "interface":
708			return p.parseInterfaceType(parent)
709		case "map":
710			return p.parseMapType(parent)
711		case "chan":
712			return p.parseChanType(parent)
713		}
714	case '@':
715		// TypeName
716		pkg, name := p.parseExportedName()
717		return declTypeName(pkg, name).Type()
718	case '[':
719		p.next() // look ahead
720		if p.tok == ']' {
721			// SliceType
722			p.next()
723			return types.NewSlice(p.parseType(parent))
724		}
725		return p.parseArrayType(parent)
726	case '*':
727		// PointerType
728		p.next()
729		return types.NewPointer(p.parseType(parent))
730	case '<':
731		return p.parseChanType(parent)
732	case '(':
733		// "(" Type ")"
734		p.next()
735		typ := p.parseType(parent)
736		p.expect(')')
737		return typ
738	}
739	p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
740	return nil
741}
742
743// ----------------------------------------------------------------------------
744// Declarations
745
746// ImportDecl = "import" PackageName PackageId .
747//
748func (p *parser) parseImportDecl() {
749	p.expectKeyword("import")
750	name := p.parsePackageName()
751	p.getPkg(p.parsePackageId(), name)
752}
753
754// int_lit = [ "+" | "-" ] { "0" ... "9" } .
755//
756func (p *parser) parseInt() string {
757	s := ""
758	switch p.tok {
759	case '-':
760		s = "-"
761		p.next()
762	case '+':
763		p.next()
764	}
765	return s + p.expect(scanner.Int)
766}
767
768// number = int_lit [ "p" int_lit ] .
769//
770func (p *parser) parseNumber() (typ *types.Basic, val exact.Value) {
771	// mantissa
772	mant := exact.MakeFromLiteral(p.parseInt(), token.INT, 0)
773	if mant == nil {
774		panic("invalid mantissa")
775	}
776
777	if p.lit == "p" {
778		// exponent (base 2)
779		p.next()
780		exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
781		if err != nil {
782			p.error(err)
783		}
784		if exp < 0 {
785			denom := exact.MakeInt64(1)
786			denom = exact.Shift(denom, token.SHL, uint(-exp))
787			typ = types.Typ[types.UntypedFloat]
788			val = exact.BinaryOp(mant, token.QUO, denom)
789			return
790		}
791		if exp > 0 {
792			mant = exact.Shift(mant, token.SHL, uint(exp))
793		}
794		typ = types.Typ[types.UntypedFloat]
795		val = mant
796		return
797	}
798
799	typ = types.Typ[types.UntypedInt]
800	val = mant
801	return
802}
803
804// ConstDecl   = "const" ExportedName [ Type ] "=" Literal .
805// Literal     = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit .
806// bool_lit    = "true" | "false" .
807// complex_lit = "(" float_lit "+" float_lit "i" ")" .
808// rune_lit    = "(" int_lit "+" int_lit ")" .
809// string_lit  = `"` { unicode_char } `"` .
810//
811func (p *parser) parseConstDecl() {
812	p.expectKeyword("const")
813	pkg, name := p.parseExportedName()
814
815	var typ0 types.Type
816	if p.tok != '=' {
817		// constant types are never structured - no need for parent type
818		typ0 = p.parseType(nil)
819	}
820
821	p.expect('=')
822	var typ types.Type
823	var val exact.Value
824	switch p.tok {
825	case scanner.Ident:
826		// bool_lit
827		if p.lit != "true" && p.lit != "false" {
828			p.error("expected true or false")
829		}
830		typ = types.Typ[types.UntypedBool]
831		val = exact.MakeBool(p.lit == "true")
832		p.next()
833
834	case '-', scanner.Int:
835		// int_lit
836		typ, val = p.parseNumber()
837
838	case '(':
839		// complex_lit or rune_lit
840		p.next()
841		if p.tok == scanner.Char {
842			p.next()
843			p.expect('+')
844			typ = types.Typ[types.UntypedRune]
845			_, val = p.parseNumber()
846			p.expect(')')
847			break
848		}
849		_, re := p.parseNumber()
850		p.expect('+')
851		_, im := p.parseNumber()
852		p.expectKeyword("i")
853		p.expect(')')
854		typ = types.Typ[types.UntypedComplex]
855		val = exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
856
857	case scanner.Char:
858		// rune_lit
859		typ = types.Typ[types.UntypedRune]
860		val = exact.MakeFromLiteral(p.lit, token.CHAR, 0)
861		p.next()
862
863	case scanner.String:
864		// string_lit
865		typ = types.Typ[types.UntypedString]
866		val = exact.MakeFromLiteral(p.lit, token.STRING, 0)
867		p.next()
868
869	default:
870		p.errorf("expected literal got %s", scanner.TokenString(p.tok))
871	}
872
873	if typ0 == nil {
874		typ0 = typ
875	}
876
877	pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val))
878}
879
880// TypeDecl = "type" ExportedName Type .
881//
882func (p *parser) parseTypeDecl() {
883	p.expectKeyword("type")
884	pkg, name := p.parseExportedName()
885	obj := declTypeName(pkg, name)
886
887	// The type object may have been imported before and thus already
888	// have a type associated with it. We still need to parse the type
889	// structure, but throw it away if the object already has a type.
890	// This ensures that all imports refer to the same type object for
891	// a given type declaration.
892	typ := p.parseType(pkg)
893
894	if name := obj.Type().(*types.Named); name.Underlying() == nil {
895		name.SetUnderlying(typ)
896	}
897}
898
899// VarDecl = "var" ExportedName Type .
900//
901func (p *parser) parseVarDecl() {
902	p.expectKeyword("var")
903	pkg, name := p.parseExportedName()
904	typ := p.parseType(pkg)
905	pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ))
906}
907
908// Func = Signature [ Body ] .
909// Body = "{" ... "}" .
910//
911func (p *parser) parseFunc(recv *types.Var) *types.Signature {
912	sig := p.parseSignature(recv)
913	if p.tok == '{' {
914		p.next()
915		for i := 1; i > 0; p.next() {
916			switch p.tok {
917			case '{':
918				i++
919			case '}':
920				i--
921			}
922		}
923	}
924	return sig
925}
926
927// MethodDecl = "func" Receiver Name Func .
928// Receiver   = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" .
929//
930func (p *parser) parseMethodDecl() {
931	// "func" already consumed
932	p.expect('(')
933	recv, _ := p.parseParameter() // receiver
934	p.expect(')')
935
936	// determine receiver base type object
937	base := deref(recv.Type()).(*types.Named)
938
939	// parse method name, signature, and possibly inlined body
940	_, name := p.parseName(nil, false)
941	sig := p.parseFunc(recv)
942
943	// methods always belong to the same package as the base type object
944	pkg := base.Obj().Pkg()
945
946	// add method to type unless type was imported before
947	// and method exists already
948	// TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small.
949	base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
950}
951
952// FuncDecl = "func" ExportedName Func .
953//
954func (p *parser) parseFuncDecl() {
955	// "func" already consumed
956	pkg, name := p.parseExportedName()
957	typ := p.parseFunc(nil)
958	pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ))
959}
960
961// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
962//
963func (p *parser) parseDecl() {
964	if p.tok == scanner.Ident {
965		switch p.lit {
966		case "import":
967			p.parseImportDecl()
968		case "const":
969			p.parseConstDecl()
970		case "type":
971			p.parseTypeDecl()
972		case "var":
973			p.parseVarDecl()
974		case "func":
975			p.next() // look ahead
976			if p.tok == '(' {
977				p.parseMethodDecl()
978			} else {
979				p.parseFuncDecl()
980			}
981		}
982	}
983	p.expect('\n')
984}
985
986// ----------------------------------------------------------------------------
987// Export
988
989// Export        = "PackageClause { Decl } "$$" .
990// PackageClause = "package" PackageName [ "safe" ] "\n" .
991//
992func (p *parser) parseExport() *types.Package {
993	p.expectKeyword("package")
994	name := p.parsePackageName()
995	if p.tok == scanner.Ident && p.lit == "safe" {
996		// package was compiled with -u option - ignore
997		p.next()
998	}
999	p.expect('\n')
1000
1001	pkg := p.getPkg(p.id, name)
1002
1003	for p.tok != '$' && p.tok != scanner.EOF {
1004		p.parseDecl()
1005	}
1006
1007	if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
1008		// don't call next()/expect() since reading past the
1009		// export data may cause scanner errors (e.g. NUL chars)
1010		p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
1011	}
1012
1013	if n := p.scanner.ErrorCount; n != 0 {
1014		p.errorf("expected no scanner errors, got %d", n)
1015	}
1016
1017	// Record all locally referenced packages as imports.
1018	var imports []*types.Package
1019	for id, pkg2 := range p.localPkgs {
1020		if pkg2.Name() == "" {
1021			p.errorf("%s package has no name", id)
1022		}
1023		if id == p.id {
1024			continue // avoid self-edge
1025		}
1026		imports = append(imports, pkg2)
1027	}
1028	sort.Sort(byPath(imports))
1029	pkg.SetImports(imports)
1030
1031	// package was imported completely and without errors
1032	pkg.MarkComplete()
1033
1034	return pkg
1035}
1036
1037type byPath []*types.Package
1038
1039func (a byPath) Len() int           { return len(a) }
1040func (a byPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
1041func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
1042