go/internal/gccgoimporter: port recent changes from stdlib version
This CL brings over the following changes from the std lib: https://golang.org/cl/137857 https://golang.org/cl/137935 https://golang.org/cl/137975 There are no further code changes except that the importer test cases are split between importer_test.go and importer19_test.go to support multiple Go versions. Updates golang/go#27856. Change-Id: I625def738c22c24c6659af37c3871038fdd8b981 Reviewed-on: https://go-review.googlesource.com/137995 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
ef4a2a23bb
commit
b14f328a62
|
@ -7,7 +7,8 @@
|
||||||
package gccgoimporter
|
package gccgoimporter
|
||||||
|
|
||||||
var aliasTests = []importerTest{
|
var aliasTests = []importerTest{
|
||||||
{pkgpath: "alias", name: "IntAlias2", want: "type IntAlias2 = Int"},
|
{pkgpath: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"},
|
||||||
|
{pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -104,7 +104,11 @@ var importerTests = []importerTest{
|
||||||
{pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
|
{pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
|
||||||
{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
|
{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
|
||||||
{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
|
{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
|
||||||
|
// moved to importer19_test.go (they import interface types)
|
||||||
|
// {pkgpath: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"},
|
||||||
|
// {pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"},
|
||||||
{pkgpath: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"},
|
{pkgpath: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"},
|
||||||
|
{pkgpath: "issue27856", name: "M", want: "type M struct{E F}"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGoxImporter(t *testing.T) {
|
func TestGoxImporter(t *testing.T) {
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package gccgoimporter
|
// This is a verbatim copy of $GOROOT/src/go/internal/gccgoimporter/parser.go
|
||||||
|
// with a small modification in parseInterface to support older Go versions.
|
||||||
|
|
||||||
// This is a verbatim copy of $GOROOT/src/go/internal/gccgoimporter/parser.go.
|
package gccgoimporter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -28,7 +29,7 @@ type parser struct {
|
||||||
pkgname string // name of imported package
|
pkgname string // name of imported package
|
||||||
pkg *types.Package // reference to imported package
|
pkg *types.Package // reference to imported package
|
||||||
imports map[string]*types.Package // package path -> package object
|
imports map[string]*types.Package // package path -> package object
|
||||||
typeMap map[int]types.Type // type number -> type
|
typeList []types.Type // type number -> type
|
||||||
initdata InitData // package init priority data
|
initdata InitData // package init priority data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ func (p *parser) init(filename string, src io.Reader, imports map[string]*types.
|
||||||
p.scanner.Filename = filename // for good error messages
|
p.scanner.Filename = filename // for good error messages
|
||||||
p.next()
|
p.next()
|
||||||
p.imports = imports
|
p.imports = imports
|
||||||
p.typeMap = make(map[int]types.Type)
|
p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
type importError struct {
|
type importError struct {
|
||||||
|
@ -380,52 +381,80 @@ func (p *parser) parseConst(pkg *types.Package) *types.Const {
|
||||||
return types.NewConst(token.NoPos, pkg, name, typ, val)
|
return types.NewConst(token.NoPos, pkg, name, typ, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reserved is a singleton type used to fill type map slots that have
|
||||||
|
// been reserved (i.e., for which a type number has been parsed) but
|
||||||
|
// which don't have their actual type yet. When the type map is updated,
|
||||||
|
// the actual type must replace a reserved entry (or we have an internal
|
||||||
|
// error). Used for self-verification only - not required for correctness.
|
||||||
|
var reserved = new(struct{ types.Type })
|
||||||
|
|
||||||
|
// reserve reserves the type map entry n for future use.
|
||||||
|
func (p *parser) reserve(n int) {
|
||||||
|
if n != len(p.typeList) {
|
||||||
|
p.errorf("invalid type number %d (out of sync)", n)
|
||||||
|
}
|
||||||
|
p.typeList = append(p.typeList, reserved)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update sets the type map entries for the given type numbers nlist to t.
|
||||||
|
func (p *parser) update(t types.Type, nlist []int) {
|
||||||
|
for _, n := range nlist {
|
||||||
|
if p.typeList[n] != reserved {
|
||||||
|
p.errorf("typeMap[%d] not reserved", n)
|
||||||
|
}
|
||||||
|
p.typeList[n] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NamedType = TypeName [ "=" ] Type { Method } .
|
// NamedType = TypeName [ "=" ] Type { Method } .
|
||||||
// TypeName = ExportedName .
|
// TypeName = ExportedName .
|
||||||
// Method = "func" "(" Param ")" Name ParamList ResultList ";" .
|
// Method = "func" "(" Param ")" Name ParamList ResultList ";" .
|
||||||
func (p *parser) parseNamedType(n int) types.Type {
|
func (p *parser) parseNamedType(nlist []int) types.Type {
|
||||||
pkg, name := p.parseExportedName()
|
pkg, name := p.parseExportedName()
|
||||||
scope := pkg.Scope()
|
scope := pkg.Scope()
|
||||||
|
obj := scope.Lookup(name)
|
||||||
if p.tok == '=' {
|
if obj != nil && obj.Type() == nil {
|
||||||
// type alias
|
p.errorf("%v has nil type", obj)
|
||||||
p.next()
|
|
||||||
typ := p.parseType(pkg)
|
|
||||||
if obj := scope.Lookup(name); obj != nil {
|
|
||||||
typ = obj.Type() // use previously imported type
|
|
||||||
if typ == nil {
|
|
||||||
p.errorf("%v (type alias) used in cycle", obj)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
obj = types.NewTypeName(token.NoPos, pkg, name, typ)
|
|
||||||
scope.Insert(obj)
|
|
||||||
}
|
|
||||||
p.typeMap[n] = typ
|
|
||||||
return typ
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// named type
|
// type alias
|
||||||
obj := scope.Lookup(name)
|
if p.tok == '=' {
|
||||||
|
p.next()
|
||||||
|
if obj != nil {
|
||||||
|
// use the previously imported (canonical) type
|
||||||
|
t := obj.Type()
|
||||||
|
p.update(t, nlist)
|
||||||
|
p.parseType(pkg) // discard
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
t := p.parseType(pkg, nlist...)
|
||||||
|
obj = types.NewTypeName(token.NoPos, pkg, name, t)
|
||||||
|
scope.Insert(obj)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// defined type
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
// a named type may be referred to before the underlying type
|
// A named type may be referred to before the underlying type
|
||||||
// is known - set it up
|
// is known - set it up.
|
||||||
tname := types.NewTypeName(token.NoPos, pkg, name, nil)
|
tname := types.NewTypeName(token.NoPos, pkg, name, nil)
|
||||||
types.NewNamed(tname, nil, nil)
|
types.NewNamed(tname, nil, nil)
|
||||||
scope.Insert(tname)
|
scope.Insert(tname)
|
||||||
obj = tname
|
obj = tname
|
||||||
}
|
}
|
||||||
|
|
||||||
typ := obj.Type()
|
// use the previously imported (canonical), or newly created type
|
||||||
p.typeMap[n] = typ
|
t := obj.Type()
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
nt, ok := typ.(*types.Named)
|
nt, ok := t.(*types.Named)
|
||||||
if !ok {
|
if !ok {
|
||||||
// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
|
// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
|
||||||
pt := p.parseType(pkg)
|
pt := p.parseType(pkg)
|
||||||
if pt != typ {
|
if pt != t {
|
||||||
p.error("unexpected underlying type for non-named TypeName")
|
p.error("unexpected underlying type for non-named TypeName")
|
||||||
}
|
}
|
||||||
return typ
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
underlying := p.parseType(pkg)
|
underlying := p.parseType(pkg)
|
||||||
|
@ -451,41 +480,70 @@ func (p *parser) parseNamedType(n int) types.Type {
|
||||||
return nt
|
return nt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) parseInt() int64 {
|
func (p *parser) parseInt64() int64 {
|
||||||
lit := p.expect(scanner.Int)
|
lit := p.expect(scanner.Int)
|
||||||
n, err := strconv.ParseInt(lit, 10, 0)
|
n, err := strconv.ParseInt(lit, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.error(err)
|
p.error(err)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *parser) parseInt() int {
|
||||||
|
lit := p.expect(scanner.Int)
|
||||||
|
n, err := strconv.ParseInt(lit, 10, 0 /* int */)
|
||||||
|
if err != nil {
|
||||||
|
p.error(err)
|
||||||
|
}
|
||||||
|
return int(n)
|
||||||
|
}
|
||||||
|
|
||||||
// ArrayOrSliceType = "[" [ int ] "]" Type .
|
// ArrayOrSliceType = "[" [ int ] "]" Type .
|
||||||
func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type {
|
func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type {
|
||||||
p.expect('[')
|
p.expect('[')
|
||||||
if p.tok == ']' {
|
if p.tok == ']' {
|
||||||
p.next()
|
p.next()
|
||||||
return types.NewSlice(p.parseType(pkg))
|
|
||||||
|
t := new(types.Slice)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
|
*t = *types.NewSlice(p.parseType(pkg))
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
n := p.parseInt()
|
t := new(types.Array)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
|
len := p.parseInt64()
|
||||||
p.expect(']')
|
p.expect(']')
|
||||||
return types.NewArray(p.parseType(pkg), n)
|
|
||||||
|
*t = *types.NewArray(p.parseType(pkg), len)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapType = "map" "[" Type "]" Type .
|
// MapType = "map" "[" Type "]" Type .
|
||||||
func (p *parser) parseMapType(pkg *types.Package) types.Type {
|
func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
|
||||||
p.expectKeyword("map")
|
p.expectKeyword("map")
|
||||||
|
|
||||||
|
t := new(types.Map)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
p.expect('[')
|
p.expect('[')
|
||||||
key := p.parseType(pkg)
|
key := p.parseType(pkg)
|
||||||
p.expect(']')
|
p.expect(']')
|
||||||
elem := p.parseType(pkg)
|
elem := p.parseType(pkg)
|
||||||
return types.NewMap(key, elem)
|
|
||||||
|
*t = *types.NewMap(key, elem)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChanType = "chan" ["<-" | "-<"] Type .
|
// ChanType = "chan" ["<-" | "-<"] Type .
|
||||||
func (p *parser) parseChanType(pkg *types.Package) types.Type {
|
func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
|
||||||
p.expectKeyword("chan")
|
p.expectKeyword("chan")
|
||||||
|
|
||||||
|
t := new(types.Chan)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
dir := types.SendRecv
|
dir := types.SendRecv
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case '-':
|
case '-':
|
||||||
|
@ -502,13 +560,17 @@ func (p *parser) parseChanType(pkg *types.Package) types.Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewChan(dir, p.parseType(pkg))
|
*t = *types.NewChan(dir, p.parseType(pkg))
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructType = "struct" "{" { Field } "}" .
|
// StructType = "struct" "{" { Field } "}" .
|
||||||
func (p *parser) parseStructType(pkg *types.Package) types.Type {
|
func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type {
|
||||||
p.expectKeyword("struct")
|
p.expectKeyword("struct")
|
||||||
|
|
||||||
|
t := new(types.Struct)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
var fields []*types.Var
|
var fields []*types.Var
|
||||||
var tags []string
|
var tags []string
|
||||||
|
|
||||||
|
@ -521,7 +583,8 @@ func (p *parser) parseStructType(pkg *types.Package) types.Type {
|
||||||
}
|
}
|
||||||
p.expect('}')
|
p.expect('}')
|
||||||
|
|
||||||
return types.NewStruct(fields, tags)
|
*t = *types.NewStruct(fields, tags)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
|
// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
|
||||||
|
@ -564,10 +627,15 @@ func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FunctionType = ParamList ResultList .
|
// FunctionType = ParamList ResultList .
|
||||||
func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
|
func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature {
|
||||||
|
t := new(types.Signature)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
params, isVariadic := p.parseParamList(pkg)
|
params, isVariadic := p.parseParamList(pkg)
|
||||||
results := p.parseResultList(pkg)
|
results := p.parseResultList(pkg)
|
||||||
return types.NewSignature(nil, params, results, isVariadic)
|
|
||||||
|
*t = *types.NewSignature(nil, params, results, isVariadic)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Func = Name FunctionType .
|
// Func = Name FunctionType .
|
||||||
|
@ -579,13 +647,16 @@ func (p *parser) parseFunc(pkg *types.Package) *types.Func {
|
||||||
p.discardDirectiveWhileParsingTypes(pkg)
|
p.discardDirectiveWhileParsingTypes(pkg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
|
return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
|
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
|
||||||
func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
|
func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type {
|
||||||
p.expectKeyword("interface")
|
p.expectKeyword("interface")
|
||||||
|
|
||||||
|
t := new(types.Interface)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
var methods []*types.Func
|
var methods []*types.Func
|
||||||
var embeddeds []types.Type
|
var embeddeds []types.Type
|
||||||
|
|
||||||
|
@ -602,53 +673,61 @@ func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
|
||||||
}
|
}
|
||||||
p.expect('}')
|
p.expect('}')
|
||||||
|
|
||||||
return newInterface(methods, embeddeds)
|
*t = *newInterface(methods, embeddeds)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// PointerType = "*" ("any" | Type) .
|
// PointerType = "*" ("any" | Type) .
|
||||||
func (p *parser) parsePointerType(pkg *types.Package) types.Type {
|
func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
|
||||||
p.expect('*')
|
p.expect('*')
|
||||||
if p.tok == scanner.Ident {
|
if p.tok == scanner.Ident {
|
||||||
p.expectKeyword("any")
|
p.expectKeyword("any")
|
||||||
return types.Typ[types.UnsafePointer]
|
t := types.Typ[types.UnsafePointer]
|
||||||
|
p.update(t, nlist)
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
return types.NewPointer(p.parseType(pkg))
|
|
||||||
|
t := new(types.Pointer)
|
||||||
|
p.update(t, nlist)
|
||||||
|
|
||||||
|
*t = *types.NewPointer(p.parseType(pkg))
|
||||||
|
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
|
// TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
|
||||||
func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type {
|
func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type {
|
||||||
var t types.Type
|
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case scanner.String:
|
case scanner.String:
|
||||||
t = p.parseNamedType(n)
|
return p.parseNamedType(nlist)
|
||||||
|
|
||||||
case scanner.Ident:
|
case scanner.Ident:
|
||||||
switch p.lit {
|
switch p.lit {
|
||||||
case "map":
|
case "map":
|
||||||
t = p.parseMapType(pkg)
|
return p.parseMapType(pkg, nlist)
|
||||||
|
|
||||||
case "chan":
|
case "chan":
|
||||||
t = p.parseChanType(pkg)
|
return p.parseChanType(pkg, nlist)
|
||||||
|
|
||||||
case "struct":
|
case "struct":
|
||||||
t = p.parseStructType(pkg)
|
return p.parseStructType(pkg, nlist)
|
||||||
|
|
||||||
case "interface":
|
case "interface":
|
||||||
t = p.parseInterfaceType(pkg)
|
return p.parseInterfaceType(pkg, nlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
t = p.parsePointerType(pkg)
|
return p.parsePointerType(pkg, nlist)
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
t = p.parseArrayOrSliceType(pkg)
|
return p.parseArrayOrSliceType(pkg, nlist)
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
t = p.parseFunctionType(pkg)
|
return p.parseFunctionType(pkg, nlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.typeMap[n] = t
|
p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
|
||||||
return t
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -702,29 +781,36 @@ func lookupBuiltinType(typ int) types.Type {
|
||||||
}[typ]
|
}[typ]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" .
|
// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
|
||||||
func (p *parser) parseType(pkg *types.Package) (t types.Type) {
|
//
|
||||||
|
// parseType updates the type map to t for all type numbers n.
|
||||||
|
//
|
||||||
|
func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) {
|
||||||
p.expect('<')
|
p.expect('<')
|
||||||
p.expectKeyword("type")
|
p.expectKeyword("type")
|
||||||
|
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case scanner.Int:
|
case scanner.Int:
|
||||||
n := p.parseInt()
|
n1 := p.parseInt()
|
||||||
|
|
||||||
if p.tok == '>' {
|
if p.tok == '>' {
|
||||||
t = p.typeMap[int(n)]
|
t = p.typeList[n1]
|
||||||
|
if t == reserved {
|
||||||
|
p.errorf("invalid type cycle, type %d not yet defined", n1)
|
||||||
|
}
|
||||||
|
p.update(t, n)
|
||||||
} else {
|
} else {
|
||||||
t = p.parseTypeDefinition(pkg, int(n))
|
p.reserve(n1)
|
||||||
|
t = p.parseTypeSpec(pkg, append(n, n1))
|
||||||
}
|
}
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
p.next()
|
p.next()
|
||||||
n := p.parseInt()
|
n1 := p.parseInt()
|
||||||
t = lookupBuiltinType(int(n))
|
t = lookupBuiltinType(n1)
|
||||||
|
p.update(t, n)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
|
p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p.expect('>')
|
p.expect('>')
|
||||||
|
@ -737,7 +823,7 @@ func (p *parser) parsePackageInit() PackageInit {
|
||||||
initfunc := p.parseUnquotedString()
|
initfunc := p.parseUnquotedString()
|
||||||
priority := -1
|
priority := -1
|
||||||
if p.version == "v1" {
|
if p.version == "v1" {
|
||||||
priority = int(p.parseInt())
|
priority = p.parseInt()
|
||||||
}
|
}
|
||||||
return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
|
return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
|
||||||
}
|
}
|
||||||
|
@ -783,7 +869,7 @@ func (p *parser) parseInitDataDirective() {
|
||||||
|
|
||||||
case "priority":
|
case "priority":
|
||||||
p.next()
|
p.next()
|
||||||
p.initdata.Priority = int(p.parseInt())
|
p.initdata.Priority = p.parseInt()
|
||||||
p.expect(';')
|
p.expect(';')
|
||||||
|
|
||||||
case "init":
|
case "init":
|
||||||
|
@ -797,8 +883,8 @@ func (p *parser) parseInitDataDirective() {
|
||||||
p.next()
|
p.next()
|
||||||
// The graph data is thrown away for now.
|
// The graph data is thrown away for now.
|
||||||
for p.tok != ';' && p.tok != scanner.EOF {
|
for p.tok != ';' && p.tok != scanner.EOF {
|
||||||
p.parseInt()
|
p.parseInt64()
|
||||||
p.parseInt()
|
p.parseInt64()
|
||||||
}
|
}
|
||||||
p.expect(';')
|
p.expect(';')
|
||||||
|
|
||||||
|
@ -900,7 +986,7 @@ func (p *parser) parsePackage() *types.Package {
|
||||||
for p.tok != scanner.EOF {
|
for p.tok != scanner.EOF {
|
||||||
p.parseDirective()
|
p.parseDirective()
|
||||||
}
|
}
|
||||||
for _, typ := range p.typeMap {
|
for _, typ := range p.typeList {
|
||||||
if it, ok := typ.(*types.Interface); ok {
|
if it, ok := typ.(*types.Interface); ok {
|
||||||
it.Complete()
|
it.Complete()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
v1;
|
|
||||||
package alias;
|
|
||||||
pkgpath alias;
|
|
||||||
type <type 115 "I1" <type 116 interface { M1 (? <type 117 "IntAlias2" = <type 118 "IntAlias" = <type 119 "Int" <type -11>>>>) < type 114>; M2 () <type 1>; }>>;
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package aliases
|
||||||
|
|
||||||
|
type (
|
||||||
|
T0 [10]int
|
||||||
|
T1 []byte
|
||||||
|
T2 struct {
|
||||||
|
x int
|
||||||
|
}
|
||||||
|
T3 interface {
|
||||||
|
m() T2
|
||||||
|
}
|
||||||
|
T4 func(int, T0) chan T2
|
||||||
|
)
|
||||||
|
|
||||||
|
// basic aliases
|
||||||
|
type (
|
||||||
|
Ai = int
|
||||||
|
A0 = T0
|
||||||
|
A1 = T1
|
||||||
|
A2 = T2
|
||||||
|
A3 = T3
|
||||||
|
A4 = T4
|
||||||
|
|
||||||
|
A10 = [10]int
|
||||||
|
A11 = []byte
|
||||||
|
A12 = struct {
|
||||||
|
x int
|
||||||
|
}
|
||||||
|
A13 = interface {
|
||||||
|
m() A2
|
||||||
|
}
|
||||||
|
A14 = func(int, A0) chan A2
|
||||||
|
)
|
||||||
|
|
||||||
|
// alias receiver types
|
||||||
|
func (T0) m1() {}
|
||||||
|
func (A0) m2() {}
|
||||||
|
|
||||||
|
// alias receiver types (long type declaration chains)
|
||||||
|
type (
|
||||||
|
V0 = V1
|
||||||
|
V1 = (V2)
|
||||||
|
V2 = (V3)
|
||||||
|
V3 = T0
|
||||||
|
)
|
||||||
|
|
||||||
|
func (V1) n() {}
|
||||||
|
|
||||||
|
// cycles
|
||||||
|
type C0 struct {
|
||||||
|
f1 C1
|
||||||
|
f2 C2
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
C1 *C0
|
||||||
|
C2 = C1
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
C5 struct {
|
||||||
|
f *C6
|
||||||
|
}
|
||||||
|
C6 = C5
|
||||||
|
)
|
|
@ -0,0 +1,33 @@
|
||||||
|
v2;
|
||||||
|
package aliases;
|
||||||
|
prefix go;
|
||||||
|
package aliases go.aliases go.aliases;
|
||||||
|
type <type 1 "A0" = <type 2 "T0" <type 3 [10 ] <type -11>>
|
||||||
|
func (? <esc:0x1> <type 2>) .go.aliases.m1 ();
|
||||||
|
func (? <esc:0x1> <type 1>) .go.aliases.m2 ();
|
||||||
|
func (? <esc:0x1> <type 4 "V1" = <type 5 "V2" = <type 6 "V3" = <type 2>>>>) .go.aliases.n ();
|
||||||
|
>>;
|
||||||
|
type <type 7 "A1" = <type 8 "T1" <type 9 [] <type -20>>>>;
|
||||||
|
type <type 10 "A10" = <type 11 [10 ] <type -11>>>;
|
||||||
|
type <type 12 "A11" = <type 13 [] <type -20>>>;
|
||||||
|
type <type 14 "A12" = <type 15 struct { .go.aliases.x <type -11>; }>>;
|
||||||
|
type <type 16 "A13" = <type 17 interface { .go.aliases.m () <type 18 "A2" = <type 19 "T2" <type 20 struct { .go.aliases.x <type -11>; }>>>; }>>;
|
||||||
|
type <type 21 "A14" = <type 22 (? <type -11>, ? <type 1>) <type 23 chan <type 18>>>>;
|
||||||
|
type <type 18>;
|
||||||
|
type <type 24 "A3" = <type 25 "T3" <type 26 interface { .go.aliases.m () <type 19>; }>>>;
|
||||||
|
type <type 27 "A4" = <type 28 "T4" <type 29 (? <type -11>, ? <type 2>) <type 30 chan <type 19>>>>>;
|
||||||
|
type <type 31 "Ai" = <type -11>>;
|
||||||
|
type <type 32 "C0" <type 33 struct { .go.aliases.f1 <type 34 "C1" <type 35 *<type 32>>>; .go.aliases.f2 <type 36 "C2" = <type 34>>; }>>;
|
||||||
|
type <type 34>;
|
||||||
|
type <type 36>;
|
||||||
|
type <type 37 "C5" <type 38 struct { .go.aliases.f <type 39 *<type 40 "C6" = <type 37>>>; }>>;
|
||||||
|
type <type 40>;
|
||||||
|
type <type 2>;
|
||||||
|
type <type 8>;
|
||||||
|
type <type 19>;
|
||||||
|
type <type 25>;
|
||||||
|
type <type 28>;
|
||||||
|
type <type 41 "V0" = <type 4>>;
|
||||||
|
type <type 4>;
|
||||||
|
type <type 5>;
|
||||||
|
type <type 6>;
|
|
@ -0,0 +1,9 @@
|
||||||
|
package lib
|
||||||
|
|
||||||
|
type M struct {
|
||||||
|
E E
|
||||||
|
}
|
||||||
|
type F struct {
|
||||||
|
_ *M
|
||||||
|
}
|
||||||
|
type E = F
|
|
@ -0,0 +1,9 @@
|
||||||
|
v2;
|
||||||
|
package main;
|
||||||
|
pkgpath main;
|
||||||
|
import runtime runtime "runtime";
|
||||||
|
init runtime runtime..import sys runtime_internal_sys..import;
|
||||||
|
init_graph 0 1;
|
||||||
|
type <type 1 "E" = <type 2 "F" <type 3 struct { .main._ <type 4 *<type 5 "M" <type 6 struct { E <type 1>; }>>>; }>>>;
|
||||||
|
type <type 2>;
|
||||||
|
type <type 5>;
|
Loading…
Reference in New Issue