Commit a7c884ef authored by Robert Griesemer's avatar Robert Griesemer

[dev.typealias] go/internal/gccgoimporter: support for type aliases

For #18130.

Change-Id: Iac182a6c5bc62633eb02191d9da6166d3b254c4c
Reviewed-on: https://go-review.googlesource.com/35268
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 5802cfd9
...@@ -101,6 +101,7 @@ var importerTests = [...]importerTest{ ...@@ -101,6 +101,7 @@ 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"}},
{pkgpath: "alias", name: "IntAlias2", want: "type IntAlias2 = Int"},
} }
func TestGoxImporter(t *testing.T) { func TestGoxImporter(t *testing.T) {
......
...@@ -370,27 +370,41 @@ func (p *parser) parseConst(pkg *types.Package) *types.Const { ...@@ -370,27 +370,41 @@ 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)
} }
// NamedType = TypeName [ "=" ] Type { Method } .
// TypeName = ExportedName . // TypeName = ExportedName .
func (p *parser) parseTypeName() *types.TypeName { // Method = "func" "(" Param ")" Name ParamList ResultList ";" .
func (p *parser) parseNamedType(n int) types.Type {
pkg, name := p.parseExportedName() pkg, name := p.parseExportedName()
scope := pkg.Scope() scope := pkg.Scope()
if p.tok == '=' {
// type alias
p.next()
typ := p.parseType(pkg)
if obj := scope.Lookup(name); obj != nil { if obj := scope.Lookup(name); obj != nil {
return obj.(*types.TypeName) typ = obj.Type() // use previously imported type
if typ == nil {
p.errorf("%v (type alias) used in cycle", obj)
} }
obj := types.NewTypeName(token.NoPos, pkg, name, nil) } else {
// a named type may be referred to before the underlying type obj = types.NewTypeName(token.NoPos, pkg, name, typ)
// is known - set it up
types.NewNamed(obj, nil, nil)
scope.Insert(obj) scope.Insert(obj)
return obj }
} p.typeMap[n] = typ
return typ
}
// NamedType = TypeName Type { Method } . // named type
// Method = "func" "(" Param ")" Name ParamList ResultList ";" . obj := scope.Lookup(name)
func (p *parser) parseNamedType(n int) types.Type { if obj == nil {
obj := p.parseTypeName() // a named type may be referred to before the underlying type
// is known - set it up
tname := types.NewTypeName(token.NoPos, pkg, name, nil)
types.NewNamed(tname, nil, nil)
scope.Insert(tname)
obj = tname
}
pkg := obj.Pkg()
typ := obj.Type() typ := obj.Type()
p.typeMap[n] = typ p.typeMap[n] = typ
...@@ -409,8 +423,8 @@ func (p *parser) parseNamedType(n int) types.Type { ...@@ -409,8 +423,8 @@ func (p *parser) parseNamedType(n int) types.Type {
nt.SetUnderlying(underlying.Underlying()) nt.SetUnderlying(underlying.Underlying())
} }
for p.tok == scanner.Ident {
// collect associated methods // collect associated methods
for p.tok == scanner.Ident {
p.expectKeyword("func") p.expectKeyword("func")
p.expect('(') p.expect('(')
receiver, _ := p.parseParam(pkg) receiver, _ := p.parseParam(pkg)
......
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>; }>>;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment