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.
5 // Except for this comment, this file is a verbatim copy of the file
6 // with the same name in $GOROOT/src/go/internal/gccgoimporter, with
7 // a small modification in parseInterface to support older Go versions.
26 scanner *scanner.Scanner
27 version string // format version
28 tok rune // current token
29 lit string // literal string; only valid for Ident, Int, String tokens
30 pkgpath string // package path of imported package
31 pkgname string // name of imported package
32 pkg *types.Package // reference to imported package
33 imports map[string]*types.Package // package path -> package object
34 typeList []types.Type // type number -> type
35 typeData []string // unparsed type data (v3 and later)
36 fixups []fixupRecord // fixups to apply at end of parsing
37 initdata InitData // package init priority data
38 aliases map[int]string // maps saved type number to alias name
41 // When reading export data it's possible to encounter a defined type
42 // N1 with an underlying defined type N2 while we are still reading in
43 // that defined type N2; see issues #29006 and #29198 for instances
52 // To handle such cases, the parser generates a fixup record (below) and
53 // delays setting of N1's underlying type until parsing is complete, at
54 // which point fixups are applied.
56 type fixupRecord struct {
57 toUpdate *types.Named // type to modify when fixup is processed
58 target types.Type // type that was incomplete when fixup was created
61 func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
62 p.scanner = new(scanner.Scanner)
63 p.initScanner(filename, src)
65 p.aliases = make(map[int]string)
66 p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
69 func (p *parser) initScanner(filename string, src io.Reader) {
71 p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
72 p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings
73 p.scanner.Whitespace = 1<<'\t' | 1<<' '
74 p.scanner.Filename = filename // for good error messages
78 type importError struct {
83 func (e importError) Error() string {
84 return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
87 func (p *parser) error(err interface{}) {
88 if s, ok := err.(string); ok {
91 // panic with a runtime.Error if err is not an error
92 panic(importError{p.scanner.Pos(), err.(error)})
95 func (p *parser) errorf(format string, args ...interface{}) {
96 p.error(fmt.Errorf(format, args...))
99 func (p *parser) expect(tok rune) string {
102 p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
108 func (p *parser) expectEOL() {
109 if p.version == "v1" || p.version == "v2" {
115 func (p *parser) expectKeyword(keyword string) {
116 lit := p.expect(scanner.Ident)
118 p.errorf("expected keyword %s, got %q", keyword, lit)
122 func (p *parser) parseString() string {
123 str, err := strconv.Unquote(p.expect(scanner.String))
130 // unquotedString = { unquotedStringChar } .
131 // unquotedStringChar = <neither a whitespace nor a ';' char> .
132 func (p *parser) parseUnquotedString() string {
133 if p.tok == scanner.EOF {
134 p.error("unexpected EOF")
137 buf.WriteString(p.scanner.TokenText())
138 // This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
139 // we need to let it be consumed by p.next().
140 for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
148 func (p *parser) next() {
149 p.tok = p.scanner.Scan()
151 case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '·':
152 p.lit = p.scanner.TokenText()
158 func (p *parser) parseQualifiedName() (path, name string) {
159 return p.parseQualifiedNameStr(p.parseString())
162 func (p *parser) parseUnquotedQualifiedName() (path, name string) {
163 return p.parseQualifiedNameStr(p.parseUnquotedString())
166 // qualifiedName = [ ["."] unquotedString "." ] unquotedString .
168 // The above production uses greedy matching.
169 func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
170 parts := strings.Split(unquotedName, ".")
177 p.errorf("malformed qualified name: %q", unquotedName)
183 // qualified name, which may contain periods
184 pkgpath = strings.Join(parts[0:len(parts)-1], ".")
185 name = parts[len(parts)-1]
191 // getPkg returns the package for a given path. If the package is
192 // not found but we have a package name, create the package and
193 // add it to the p.imports map.
195 func (p *parser) getPkg(pkgpath, name string) *types.Package {
196 // package unsafe is not in the imports map - handle explicitly
197 if pkgpath == "unsafe" {
200 pkg := p.imports[pkgpath]
201 if pkg == nil && name != "" {
202 pkg = types.NewPackage(pkgpath, name)
203 p.imports[pkgpath] = pkg
208 // parseExportedName is like parseQualifiedName, but
209 // the package path is resolved to an imported *types.Package.
211 // ExportedName = string [string] .
212 func (p *parser) parseExportedName() (pkg *types.Package, name string) {
213 path, name := p.parseQualifiedName()
215 if p.tok == scanner.String {
216 pkgname = p.parseString()
218 pkg = p.getPkg(path, pkgname)
220 p.errorf("package %s (path = %q) not found", name, path)
225 // Name = QualifiedName | "?" .
226 func (p *parser) parseName() string {
232 // The package path is redundant for us. Don't try to parse it.
233 _, name := p.parseUnquotedQualifiedName()
237 func deref(typ types.Type) types.Type {
238 if p, _ := typ.(*types.Pointer); p != nil {
244 // Field = Name Type [string] .
245 func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
246 name := p.parseName()
247 typ, n := p.parseTypeExtended(pkg)
252 if aname, ok := p.aliases[n]; ok {
255 switch typ := deref(typ).(type) {
259 name = typ.Obj().Name()
261 p.error("embedded field expected")
265 field = types.NewField(token.NoPos, pkg, name, typ, anon)
266 if p.tok == scanner.String {
267 tag = p.parseString()
272 // Param = Name ["..."] Type .
273 func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
274 name := p.parseName()
275 // Ignore names invented for inlinable functions.
276 if strings.HasPrefix(name, "p.") || strings.HasPrefix(name, "r.") || strings.HasPrefix(name, "$ret") {
279 if p.tok == '<' && p.scanner.Peek() == 'e' {
280 // EscInfo = "<esc:" int ">" . (optional and ignored)
282 p.expectKeyword("esc")
284 p.expect(scanner.Int)
293 typ := p.parseType(pkg)
295 typ = types.NewSlice(typ)
297 param = types.NewParam(token.NoPos, pkg, name, typ)
302 func (p *parser) parseVar(pkg *types.Package) *types.Var {
303 name := p.parseName()
304 v := types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
305 if name[0] == '.' || name[0] == '<' {
306 // This is an unexported variable,
307 // or a variable defined in a different package.
308 // We only want to record exported variables.
314 // Conversion = "convert" "(" Type "," ConstValue ")" .
315 func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
316 p.expectKeyword("convert")
318 typ = p.parseType(pkg)
320 val, _ = p.parseConstValue(pkg)
325 // ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
326 // FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
327 func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
328 // v3 changed to $false, $true, $convert, to avoid confusion
329 // with variable names in inline function bodies.
332 if p.tok != scanner.Ident {
333 p.errorf("expected identifier after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit)
339 str := p.parseString()
340 val = constant.MakeString(str)
341 typ = types.Typ[types.UntypedString]
352 return p.parseConversion(pkg)
355 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
359 val = constant.MakeBool(b)
360 typ = types.Typ[types.UntypedBool]
372 val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
374 p.error("could not parse integer literal")
380 typ = types.Typ[types.UntypedRune]
382 typ = types.Typ[types.UntypedInt]
393 im = p.expect(scanner.Float)
397 im = "-" + p.expect(scanner.Float)
400 // re is in fact the imaginary component. Expect "i" below.
405 val = constant.MakeFromLiteral(re, token.FLOAT, 0)
407 p.error("could not parse float literal")
409 typ = types.Typ[types.UntypedFloat]
414 reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
416 p.error("could not parse real component of complex literal")
418 imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
420 p.error("could not parse imag component of complex literal")
422 val = constant.BinaryOp(reval, token.ADD, imval)
423 typ = types.Typ[types.UntypedComplex]
426 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
432 // Const = Name [Type] "=" ConstValue .
433 func (p *parser) parseConst(pkg *types.Package) *types.Const {
434 name := p.parseName()
437 typ = p.parseType(pkg)
440 val, vtyp := p.parseConstValue(pkg)
444 return types.NewConst(token.NoPos, pkg, name, typ, val)
447 // reserved is a singleton type used to fill type map slots that have
448 // been reserved (i.e., for which a type number has been parsed) but
449 // which don't have their actual type yet. When the type map is updated,
450 // the actual type must replace a reserved entry (or we have an internal
451 // error). Used for self-verification only - not required for correctness.
452 var reserved = new(struct{ types.Type })
454 // reserve reserves the type map entry n for future use.
455 func (p *parser) reserve(n int) {
457 // - for pre-V3 export data, the type numbers we see are
458 // guaranteed to be in increasing order, so we append a
459 // reserved entry onto the list.
460 // - for V3+ export data, type numbers can appear in
461 // any order, however the 'types' section tells us the
462 // total number of types, hence typeList is pre-allocated.
463 if len(p.typeData) == 0 {
464 if n != len(p.typeList) {
465 p.errorf("invalid type number %d (out of sync)", n)
467 p.typeList = append(p.typeList, reserved)
469 if p.typeList[n] != nil {
470 p.errorf("previously visited type number %d", n)
472 p.typeList[n] = reserved
476 // update sets the type map entries for the entries in nlist to t.
477 // An entry in nlist can be a type number in p.typeList,
478 // used to resolve named types, or it can be a *types.Pointer,
479 // used to resolve pointers to named types in case they are referenced
480 // by embedded fields.
481 func (p *parser) update(t types.Type, nlist []interface{}) {
483 p.errorf("internal error: update(%v) invoked on reserved", nlist)
486 p.errorf("internal error: update(%v) invoked on nil", nlist)
488 for _, n := range nlist {
489 switch n := n.(type) {
491 if p.typeList[n] == t {
494 if p.typeList[n] != reserved {
495 p.errorf("internal error: update(%v): %d not reserved", nlist, n)
499 if *n != (types.Pointer{}) {
504 p.errorf("internal error: update: pointer already set to %v, expected %v", elem, t)
506 *n = *types.NewPointer(t)
508 p.errorf("internal error: %T on nlist", n)
513 // NamedType = TypeName [ "=" ] Type { Method } .
514 // TypeName = ExportedName .
515 // Method = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
516 func (p *parser) parseNamedType(nlist []interface{}) types.Type {
517 pkg, name := p.parseExportedName()
519 obj := scope.Lookup(name)
520 if obj != nil && obj.Type() == nil {
521 p.errorf("%v has nil type", obj)
524 if p.tok == scanner.Ident && p.lit == "notinheap" {
526 // The go/types package has no way of recording that
527 // this type is marked notinheap. Presumably no user
528 // of this package actually cares.
534 p.aliases[nlist[len(nlist)-1].(int)] = name
536 // use the previously imported (canonical) type
539 p.parseType(pkg) // discard
542 t := p.parseType(pkg, nlist...)
543 obj = types.NewTypeName(token.NoPos, pkg, name, t)
550 // A named type may be referred to before the underlying type
551 // is known - set it up.
552 tname := types.NewTypeName(token.NoPos, pkg, name, nil)
553 types.NewNamed(tname, nil, nil)
558 // use the previously imported (canonical), or newly created type
562 nt, ok := t.(*types.Named)
564 // This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
565 pt := p.parseType(pkg)
567 p.error("unexpected underlying type for non-named TypeName")
572 underlying := p.parseType(pkg)
573 if nt.Underlying() == nil {
574 if underlying.Underlying() == nil {
575 fix := fixupRecord{toUpdate: nt, target: underlying}
576 p.fixups = append(p.fixups, fix)
578 nt.SetUnderlying(underlying.Underlying())
584 // collect associated methods
585 for p.tok == scanner.Ident {
586 p.expectKeyword("func")
588 // Skip a /*nointerface*/ or /*asm ID */ comment.
591 if p.expect(scanner.Ident) == "asm" {
592 p.parseUnquotedString()
598 receiver, _ := p.parseParam(pkg)
600 name := p.parseName()
601 params, isVariadic := p.parseParamList(pkg)
602 results := p.parseResultList(pkg)
606 sig := types.NewSignature(receiver, params, results, isVariadic)
607 nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
614 func (p *parser) parseInt64() int64 {
615 lit := p.expect(scanner.Int)
616 n, err := strconv.ParseInt(lit, 10, 64)
623 func (p *parser) parseInt() int {
624 lit := p.expect(scanner.Int)
625 n, err := strconv.ParseInt(lit, 10, 0 /* int */)
632 // ArrayOrSliceType = "[" [ int ] "]" Type .
633 func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []interface{}) types.Type {
638 t := new(types.Slice)
641 *t = *types.NewSlice(p.parseType(pkg))
645 t := new(types.Array)
648 len := p.parseInt64()
651 *t = *types.NewArray(p.parseType(pkg), len)
655 // MapType = "map" "[" Type "]" Type .
656 func (p *parser) parseMapType(pkg *types.Package, nlist []interface{}) types.Type {
657 p.expectKeyword("map")
663 key := p.parseType(pkg)
665 elem := p.parseType(pkg)
667 *t = *types.NewMap(key, elem)
671 // ChanType = "chan" ["<-" | "-<"] Type .
672 func (p *parser) parseChanType(pkg *types.Package, nlist []interface{}) types.Type {
673 p.expectKeyword("chan")
678 dir := types.SendRecv
686 // don't consume '<' if it belongs to Type
687 if p.scanner.Peek() == '-' {
694 *t = *types.NewChan(dir, p.parseType(pkg))
698 // StructType = "struct" "{" { Field } "}" .
699 func (p *parser) parseStructType(pkg *types.Package, nlist []interface{}) types.Type {
700 p.expectKeyword("struct")
702 t := new(types.Struct)
705 var fields []*types.Var
709 for p.tok != '}' && p.tok != scanner.EOF {
710 field, tag := p.parseField(pkg)
712 fields = append(fields, field)
713 tags = append(tags, tag)
717 *t = *types.NewStruct(fields, tags)
721 // ParamList = "(" [ { Parameter "," } Parameter ] ")" .
722 func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
723 var list []*types.Var
727 for p.tok != ')' && p.tok != scanner.EOF {
731 par, variadic := p.parseParam(pkg)
732 list = append(list, par)
735 p.error("... not on final argument")
742 return types.NewTuple(list...), isVariadic
745 // ResultList = Type | ParamList .
746 func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
750 if p.tok == scanner.Ident && p.lit == "inl" {
753 taa, _ := p.parseTypeAfterAngle(pkg)
754 return types.NewTuple(types.NewParam(token.NoPos, pkg, "", taa))
757 params, _ := p.parseParamList(pkg)
765 // FunctionType = ParamList ResultList .
766 func (p *parser) parseFunctionType(pkg *types.Package, nlist []interface{}) *types.Signature {
767 t := new(types.Signature)
770 params, isVariadic := p.parseParamList(pkg)
771 results := p.parseResultList(pkg)
773 *t = *types.NewSignature(nil, params, results, isVariadic)
777 // Func = Name FunctionType [InlineBody] .
778 func (p *parser) parseFunc(pkg *types.Package) *types.Func {
780 // Skip an /*asm ID */ comment.
783 if p.expect(scanner.Ident) == "asm" {
784 p.parseUnquotedString()
790 name := p.parseName()
791 f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
794 if name[0] == '.' || name[0] == '<' || strings.ContainsRune(name, '$') {
795 // This is an unexported function,
796 // or a function defined in a different package,
797 // or a type$equal or type$hash function.
798 // We only want to record exported functions.
805 // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
806 func (p *parser) parseInterfaceType(pkg *types.Package, nlist []interface{}) types.Type {
807 p.expectKeyword("interface")
809 t := new(types.Interface)
812 var methods []*types.Func
813 var embeddeds []types.Type
816 for p.tok != '}' && p.tok != scanner.EOF {
819 embeddeds = append(embeddeds, p.parseType(pkg))
821 method := p.parseFunc(pkg)
823 methods = append(methods, method)
830 *t = *newInterface(methods, embeddeds)
834 // PointerType = "*" ("any" | Type) .
835 func (p *parser) parsePointerType(pkg *types.Package, nlist []interface{}) types.Type {
837 if p.tok == scanner.Ident {
838 p.expectKeyword("any")
839 t := types.Typ[types.UnsafePointer]
844 t := new(types.Pointer)
847 *t = *types.NewPointer(p.parseType(pkg, t))
852 // TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
853 func (p *parser) parseTypeSpec(pkg *types.Package, nlist []interface{}) types.Type {
856 return p.parseNamedType(nlist)
861 return p.parseMapType(pkg, nlist)
864 return p.parseChanType(pkg, nlist)
867 return p.parseStructType(pkg, nlist)
870 return p.parseInterfaceType(pkg, nlist)
874 return p.parsePointerType(pkg, nlist)
877 return p.parseArrayOrSliceType(pkg, nlist)
880 return p.parseFunctionType(pkg, nlist)
883 p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
888 // From gofrontend/go/export.h
889 // Note that these values are negative in the gofrontend and have been made positive
890 // in the gccgoimporter.
892 gccgoBuiltinINT16 = 2
893 gccgoBuiltinINT32 = 3
894 gccgoBuiltinINT64 = 4
895 gccgoBuiltinUINT8 = 5
896 gccgoBuiltinUINT16 = 6
897 gccgoBuiltinUINT32 = 7
898 gccgoBuiltinUINT64 = 8
899 gccgoBuiltinFLOAT32 = 9
900 gccgoBuiltinFLOAT64 = 10
902 gccgoBuiltinUINT = 12
903 gccgoBuiltinUINTPTR = 13
904 gccgoBuiltinBOOL = 15
905 gccgoBuiltinSTRING = 16
906 gccgoBuiltinCOMPLEX64 = 17
907 gccgoBuiltinCOMPLEX128 = 18
908 gccgoBuiltinERROR = 19
909 gccgoBuiltinBYTE = 20
910 gccgoBuiltinRUNE = 21
913 func lookupBuiltinType(typ int) types.Type {
914 return [...]types.Type{
915 gccgoBuiltinINT8: types.Typ[types.Int8],
916 gccgoBuiltinINT16: types.Typ[types.Int16],
917 gccgoBuiltinINT32: types.Typ[types.Int32],
918 gccgoBuiltinINT64: types.Typ[types.Int64],
919 gccgoBuiltinUINT8: types.Typ[types.Uint8],
920 gccgoBuiltinUINT16: types.Typ[types.Uint16],
921 gccgoBuiltinUINT32: types.Typ[types.Uint32],
922 gccgoBuiltinUINT64: types.Typ[types.Uint64],
923 gccgoBuiltinFLOAT32: types.Typ[types.Float32],
924 gccgoBuiltinFLOAT64: types.Typ[types.Float64],
925 gccgoBuiltinINT: types.Typ[types.Int],
926 gccgoBuiltinUINT: types.Typ[types.Uint],
927 gccgoBuiltinUINTPTR: types.Typ[types.Uintptr],
928 gccgoBuiltinBOOL: types.Typ[types.Bool],
929 gccgoBuiltinSTRING: types.Typ[types.String],
930 gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64],
931 gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
932 gccgoBuiltinERROR: types.Universe.Lookup("error").Type(),
933 gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(),
934 gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(),
938 // Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
940 // parseType updates the type map to t for all type numbers n.
942 func (p *parser) parseType(pkg *types.Package, n ...interface{}) types.Type {
944 t, _ := p.parseTypeAfterAngle(pkg, n...)
948 // (*parser).Type after reading the "<".
949 func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
950 p.expectKeyword("type")
957 if len(p.typeData) > 0 && p.typeList[n1] == nil {
958 p.parseSavedType(pkg, n1, n)
961 if len(p.typeData) == 0 && t == reserved {
962 p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n)
967 t = p.parseTypeSpec(pkg, append(n, n1))
973 t = lookupBuiltinType(n1)
977 p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
981 if t == nil || t == reserved {
982 p.errorf("internal error: bad return from parseType(%v)", n)
989 // parseTypeExtended is identical to parseType, but if the type in
990 // question is a saved type, returns the index as well as the type
991 // pointer (index returned is zero if we parsed a builtin).
992 func (p *parser) parseTypeExtended(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
994 t, n1 = p.parseTypeAfterAngle(pkg, n...)
998 // InlineBody = "<inl:NN>" .{NN}
999 // Reports whether a body was skipped.
1000 func (p *parser) skipInlineBody() {
1001 // We may or may not have seen the '<' already, depending on
1002 // whether the function had a result type or not.
1005 p.expectKeyword("inl")
1006 } else if p.tok != scanner.Ident || p.lit != "inl" {
1013 want := p.parseInt()
1016 defer func(w uint64) {
1017 p.scanner.Whitespace = w
1018 }(p.scanner.Whitespace)
1019 p.scanner.Whitespace = 0
1023 r := p.scanner.Next()
1024 if r == scanner.EOF {
1025 p.error("unexpected EOF")
1027 got += utf8.RuneLen(r)
1031 // Types = "types" maxp1 exportedp1 (offset length)* .
1032 func (p *parser) parseTypes(pkg *types.Package) {
1033 maxp1 := p.parseInt()
1034 exportedp1 := p.parseInt()
1035 p.typeList = make([]types.Type, maxp1)
1037 type typeOffset struct {
1041 var typeOffsets []typeOffset
1044 for i := 1; i < maxp1; i++ {
1046 typeOffsets = append(typeOffsets, typeOffset{total, len})
1050 defer func(w uint64) {
1051 p.scanner.Whitespace = w
1052 }(p.scanner.Whitespace)
1053 p.scanner.Whitespace = 0
1055 // We should now have p.tok pointing to the final newline.
1056 // The next runes from the scanner should be the type data.
1058 var sb strings.Builder
1059 for sb.Len() < total {
1060 r := p.scanner.Next()
1061 if r == scanner.EOF {
1062 p.error("unexpected EOF")
1066 allTypeData := sb.String()
1068 p.typeData = []string{""} // type 0, unused
1069 for _, to := range typeOffsets {
1070 p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length])
1073 for i := 1; i < int(exportedp1); i++ {
1074 p.parseSavedType(pkg, i, nil)
1078 // parseSavedType parses one saved type definition.
1079 func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []interface{}) {
1080 defer func(s *scanner.Scanner, tok rune, lit string) {
1084 }(p.scanner, p.tok, p.lit)
1086 p.scanner = new(scanner.Scanner)
1087 p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i]))
1088 p.expectKeyword("type")
1091 p.errorf("type ID mismatch: got %d, want %d", id, i)
1093 if p.typeList[i] == reserved {
1094 p.errorf("internal error: %d already reserved in parseSavedType", i)
1096 if p.typeList[i] == nil {
1098 p.parseTypeSpec(pkg, append(nlist, i))
1100 if p.typeList[i] == nil || p.typeList[i] == reserved {
1101 p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist)
1105 // PackageInit = unquotedString unquotedString int .
1106 func (p *parser) parsePackageInit() PackageInit {
1107 name := p.parseUnquotedString()
1108 initfunc := p.parseUnquotedString()
1110 if p.version == "v1" {
1111 priority = p.parseInt()
1113 return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
1116 // Create the package if we have parsed both the package path and package name.
1117 func (p *parser) maybeCreatePackage() {
1118 if p.pkgname != "" && p.pkgpath != "" {
1119 p.pkg = p.getPkg(p.pkgpath, p.pkgname)
1123 // InitDataDirective = ( "v1" | "v2" | "v3" ) ";" |
1124 // "priority" int ";" |
1125 // "init" { PackageInit } ";" |
1126 // "checksum" unquotedString ";" .
1127 func (p *parser) parseInitDataDirective() {
1128 if p.tok != scanner.Ident {
1129 // unexpected token kind; panic
1130 p.expect(scanner.Ident)
1134 case "v1", "v2", "v3":
1142 p.initdata.Priority = p.parseInt()
1147 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
1148 p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
1154 // The graph data is thrown away for now.
1155 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
1162 // Don't let the scanner try to parse the checksum as a number.
1163 defer func(mode uint) {
1164 p.scanner.Mode = mode
1166 p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
1168 p.parseUnquotedString()
1172 p.errorf("unexpected identifier: %q", p.lit)
1176 // Directive = InitDataDirective |
1177 // "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
1178 // "pkgpath" unquotedString ";" |
1179 // "prefix" unquotedString ";" |
1180 // "import" unquotedString unquotedString string ";" |
1181 // "indirectimport" unquotedString unquotedstring ";" |
1182 // "func" Func ";" |
1183 // "type" Type ";" |
1185 // "const" Const ";" .
1186 func (p *parser) parseDirective() {
1187 if p.tok != scanner.Ident {
1188 // unexpected token kind; panic
1189 p.expect(scanner.Ident)
1193 case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
1194 p.parseInitDataDirective()
1198 p.pkgname = p.parseUnquotedString()
1199 p.maybeCreatePackage()
1200 if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
1201 p.parseUnquotedString()
1202 p.parseUnquotedString()
1208 p.pkgpath = p.parseUnquotedString()
1209 p.maybeCreatePackage()
1214 p.pkgpath = p.parseUnquotedString()
1219 pkgname := p.parseUnquotedString()
1220 pkgpath := p.parseUnquotedString()
1221 p.getPkg(pkgpath, pkgname)
1225 case "indirectimport":
1227 pkgname := p.parseUnquotedString()
1228 pkgpath := p.parseUnquotedString()
1229 p.getPkg(pkgpath, pkgname)
1239 fun := p.parseFunc(p.pkg)
1241 p.pkg.Scope().Insert(fun)
1252 v := p.parseVar(p.pkg)
1254 p.pkg.Scope().Insert(v)
1260 c := p.parseConst(p.pkg)
1261 p.pkg.Scope().Insert(c)
1265 p.errorf("unexpected identifier: %q", p.lit)
1269 // Package = { Directive } .
1270 func (p *parser) parsePackage() *types.Package {
1271 for p.tok != scanner.EOF {
1274 for _, f := range p.fixups {
1275 if f.target.Underlying() == nil {
1276 p.errorf("internal error: fixup can't be applied, loop required")
1278 f.toUpdate.SetUnderlying(f.target.Underlying())
1281 for _, typ := range p.typeList {
1282 if it, ok := typ.(*types.Interface); ok {
1286 p.pkg.MarkComplete()