]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typealias] go/internal/gccgoimporter: support for type aliases
authorRobert Griesemer <gri@golang.org>
Tue, 17 Jan 2017 23:06:04 +0000 (15:06 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 20 Jan 2017 05:57:33 +0000 (05:57 +0000)
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: Alan Donovan <adonovan@google.com>
src/go/internal/gccgoimporter/importer_test.go
src/go/internal/gccgoimporter/parser.go
src/go/internal/gccgoimporter/testdata/alias.gox [new file with mode: 0644]

index 2b454701beb0026c66bf6ee74fa3852aa09b0901..4fca828bf607344121016b57f19e591d2d20487a 100644 (file)
@@ -101,6 +101,7 @@ var importerTests = [...]importerTest{
        {pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
        {pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
        {pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
+       {pkgpath: "alias", name: "IntAlias2", want: "type IntAlias2 = Int"},
 }
 
 func TestGoxImporter(t *testing.T) {
index 3b97c96d433fb016009fb8734cdeaec1e5b7e6d6..0d788653e37a31f4b1a44d97c021d19ff2fa78e4 100644 (file)
@@ -370,27 +370,41 @@ func (p *parser) parseConst(pkg *types.Package) *types.Const {
        return types.NewConst(token.NoPos, pkg, name, typ, val)
 }
 
-// TypeName = ExportedName .
-func (p *parser) parseTypeName() *types.TypeName {
+// NamedType = TypeName [ "=" ] Type { Method } .
+// TypeName  = ExportedName .
+// Method    = "func" "(" Param ")" Name ParamList ResultList ";" .
+func (p *parser) parseNamedType(n int) types.Type {
        pkg, name := p.parseExportedName()
        scope := pkg.Scope()
-       if obj := scope.Lookup(name); obj != nil {
-               return obj.(*types.TypeName)
+
+       if p.tok == '=' {
+               // type alias
+               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
        }
-       obj := types.NewTypeName(token.NoPos, pkg, name, nil)
-       // a named type may be referred to before the underlying type
-       // is known - set it up
-       types.NewNamed(obj, nil, nil)
-       scope.Insert(obj)
-       return obj
-}
 
-// NamedType = TypeName Type { Method } .
-// Method    = "func" "(" Param ")" Name ParamList ResultList ";" .
-func (p *parser) parseNamedType(n int) types.Type {
-       obj := p.parseTypeName()
+       // named type
+       obj := scope.Lookup(name)
+       if obj == nil {
+               // 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()
        p.typeMap[n] = typ
 
@@ -409,8 +423,8 @@ func (p *parser) parseNamedType(n int) types.Type {
                nt.SetUnderlying(underlying.Underlying())
        }
 
+       // collect associated methods
        for p.tok == scanner.Ident {
-               // collect associated methods
                p.expectKeyword("func")
                p.expect('(')
                receiver, _ := p.parseParam(pkg)
diff --git a/src/go/internal/gccgoimporter/testdata/alias.gox b/src/go/internal/gccgoimporter/testdata/alias.gox
new file mode 100644 (file)
index 0000000..ced7d84
--- /dev/null
@@ -0,0 +1,4 @@
+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>; }>>;